我正在研究一段时间来查找信息如何使用PyQT执行多线程程序,更新GUI以显示结果。更新MultiThreaded PyQT中的GUI元素
我习惯于通过示例进行学习,但找不到(是的,我正在寻找几周)任何使用多线程程序的简单示例,可以执行诸如连接到www站点列表(5个线程)等简单任务,只需打印带响应代码的处理过的网址即可。
任何人都可以共享代码或发送给我很好的教程,这样的程序解释?
我正在研究一段时间来查找信息如何使用PyQT执行多线程程序,更新GUI以显示结果。更新MultiThreaded PyQT中的GUI元素
我习惯于通过示例进行学习,但找不到(是的,我正在寻找几周)任何使用多线程程序的简单示例,可以执行诸如连接到www站点列表(5个线程)等简单任务,只需打印带响应代码的处理过的网址即可。
任何人都可以共享代码或发送给我很好的教程,这样的程序解释?
这里有一些非常基本的例子。
您可以将对GUI元素的引用传递给线程,并在线程中更新它们。
import sys
import urllib2
from PyQt4 import QtCore, QtGui
class DownloadThread(QtCore.QThread):
def __init__(self, url, list_widget):
QtCore.QThread.__init__(self)
self.url = url
self.list_widget = list_widget
def run(self):
info = urllib2.urlopen(self.url).info()
self.list_widget.addItem('%s\n%s' % (self.url, info))
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.list_widget = QtGui.QListWidget()
self.button = QtGui.QPushButton("Start")
self.button.clicked.connect(self.start_download)
layout = QtGui.QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.list_widget)
self.setLayout(layout)
def start_download(self):
urls = ['http://google.com', 'http://twitter.com', 'http://yandex.ru',
'http://stackoverflow.com/', 'http://www.youtube.com/']
self.threads = []
for url in urls:
downloader = DownloadThread(url, self.list_widget)
self.threads.append(downloader)
downloader.start()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
编者按: Qt控件不是线程安全的,不应由任何线程,但主线程(见Qt documentation了解详细信息)进行访问。正如本答案的第二部分所示,使用线程的正确方法是通过信号/插槽。
另外,您可以使用信号和插槽来分离gui和网络逻辑。
import sys
import urllib2
from PyQt4 import QtCore, QtGui
class DownloadThread(QtCore.QThread):
data_downloaded = QtCore.pyqtSignal(object)
def __init__(self, url):
QtCore.QThread.__init__(self)
self.url = url
def run(self):
info = urllib2.urlopen(self.url).info()
self.data_downloaded.emit('%s\n%s' % (self.url, info))
class MainWindow(QtGui.QWidget):
def __init__(self):
super(MainWindow, self).__init__()
self.list_widget = QtGui.QListWidget()
self.button = QtGui.QPushButton("Start")
self.button.clicked.connect(self.start_download)
layout = QtGui.QVBoxLayout()
layout.addWidget(self.button)
layout.addWidget(self.list_widget)
self.setLayout(layout)
def start_download(self):
urls = ['http://google.com', 'http://twitter.com', 'http://yandex.ru',
'http://stackoverflow.com/', 'http://www.youtube.com/']
self.threads = []
for url in urls:
downloader = DownloadThread(url)
downloader.data_downloaded.connect(self.on_data_ready)
self.threads.append(downloader)
downloader.start()
def on_data_ready(self, data):
print data
self.list_widget.addItem(unicode(data))
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.resize(640, 480)
window.show()
sys.exit(app.exec_())
哎,我没试过PyQt的,但我在pygtk的使用多线程。在pygtk中,gobject通常用于这样做。你应该搜索pyQt类似的东西。 – Froyo 2012-03-31 16:36:28
另请参阅http://stackoverflow.com/questions/11265812/pyside-pyqt-starting-a-cpu-intensive-thread-hangs-the-whole-application,http://stackoverflow.com/questions/16879971/example -of-the-right-way-to-use-qthread-in-pyqt,http://stackoverflow.com/questions/6783194/background-thread-with-qthread-in-pyqt或http://stackoverflow.com/questions/20752154/pyqt-connecting-a-signal-to-a-slot-to-start-a-background-operation – Trilarion 2015-01-07 09:44:15