在multithreadingPyQT中更新GUI元素

我正在研究一段时间来find信息如何使用PyQT做multithreading程序,更新GUI来显示结果

我习惯于通过示例学习,我找不到(是的,我正在寻找几个星期)任何简单的例子程序使用multithreading做这样简单的任务,例如连接到www站点列表(5线程),只是打印处理与响应代码的url。

任何人都可以共享代码或发送给我很好的教程,这样的程序解释?

这里有一些很基本的例子。

您可以将对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文档以获取更多详细信息)。 本答案的第二部分显示了使用线程的正确方法是通过信号/插槽。


另外,您可以使用信号和插槽来分离GUI和networking逻辑。

 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_())