我研究了一段时间,以查找有关 如何使用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文档)。正确使用线程的方法是通过信号/插槽,如答案第二部分所示。
另外,您可以使用信号和插槽来分隔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_())
问题内容: 您好,我想知道从swingworkerthread向jtextarea添加文本的最佳方法是什么,我创建了另一个类,Threadsclass()。execute()调用了jbutton。并且线程与此代码并行运行 现在id要做的是将x的值添加到主gui上的文本区域,任何想法都值得赞赏。 问题答案: JavaDocs有一个很好的例子 看一下发布和处理 潜在的意图是,您仅需要从事件调度线程中更
问题内容: 我用javafx做棋盘游戏,偶然发现一个问题。我的应用程序具有客户端/服务器连接。每当服务器发送有关玩家将棋子移动到何处的数据时,我都会调用一个函数pawnPawn()来移动棋子,并调用另一个函数refresh()来重新绘制棋盘和棋子。不幸的是,我收到错误消息,说该函数是从不是FX的线程调用的,因此无法继续执行。我尝试了任务和Platform.runLater,但要么做错了,要么不起作
我有一个带有一些线程的简单应用程序,我需要从一些线程更新SWING GUI(我正在使用Netbean)。 这是我需要更新的主要表单: 现在我有一些线程: 在其他班级,我有: 代码的每个部分都位于不同的文件(类)中。我如何在这里实现 Swing 工作人员,以便能够在我的主 GUI 窗体上显示文本?
问题内容: 在此代码中,addRemote方法使用新按钮更新controlPnl GUI。dmc.moveTo方法中最多包含两个Thread.sleep调用,我认为在controlPnl GUI更新之前已调用了它们。我已经注释了dmc.moveTo之后的两个方法调用,这些方法将GUI恢复为调用之前的状态,并且controlPnl直到moveTo完成执行后才完成更新。我需要GUI在moveTo方法开
问题内容: 嗨,我已经发送到GUI的线程工作程序链接,并直接从QThread更新GUI信息。像这儿: 在主要我只是添加 这样的解决方案在PyQt5中非常不好吗?我是PyQt的新手。谢谢。如果我的解决方案不好,请帮助我修复它。 问题答案: 您不能也不能从辅助线程更新GUI,必须通过信号和插槽来完成: 为此,我们将通过class创建一个信号,并将指示参数的类型,然后将其连接到所需的插槽,如下所示: 线
所以我有这样的东西: 一切都很好,直到我不得不等待其他事情完成,然后才能继续运行,所以我这样修改了它: 后来我做了这样的事情: 现在,我的gui在切换场景时开始滞后 - 这意味着 - 整个thread1自行处理,然后gui加载所有内容。经过一些研究,我认为发生这种情况是因为主线程正在处理runLater“请求”,并且由于wait(),主线程必须等到第一个辅助线程来到CountDown()。 我的问