【问题标题】:Threading a method for a PyQT GUI线程化 PyQT GUI 的方法
【发布时间】:2017-10-18 16:44:40
【问题描述】:

我有一个 pyqt GUI 和一个方法 [BigramClassification()],它会导致 GUI 挂起几秒钟。因此,我发现需要使用线程。所以在阅读了几个教程后,我想出了以下代码。

import sys,os

from PyQt4 import QtCore, QtGui
from PyQt4.QtCore import QThread
import time

class MyForm(QtGui.QMainWindow):

    def __init__(self, parent=None):

        QtGui.QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)
        self.ui.lblHistory.setPixmap(QtGui.QPixmap(os.getcwd() + "/historygraph.png"))

        self.workerThread=WorkingThread()
        self.ui.pushButton.clicked.connect(self.generateDetails)
        self.ui.btnsubmitsettings.clicked.connect(self.addDetails)



    def generateDetails(self):
        self.workerThread.start()
        self.ui.lblHistory.setPixmap(QtGui.QPixmap(os.getcwd() + "/historygraph.png"))
        self.addPiechart()
        self.addWordCloud()
        self.summaryText()


    def addPiechart(self):

        print ("Added")

    def addWordCloud(self):

        print ("Added")

    def addDetails(self):


    def summaryText(self):

        print("Added")

class WorkingThread(QThread):
    def __init__(self, parent=None):
        super(self.__class__, self).__init__(parent)

    def run(self):
        BigramsClassifier()

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)

    myapp = MyForm()
    myapp.show()
    sys.exit(app.exec_())

我遇到的问题是,当我运行它并单击pushButton 时,线程启动但也执行start() 之后的方法,如def generateDetails(self): 中所示,我需要准备此代码,以便@987654327 中的方法@在线程执行完毕后执行,重方法BigramClassification()execution。

总结我怎样才能停止def generateDetails(self):中方法的自动执行,但只有在方法BigramClassification()完成之后。

EDIT 当我尝试关闭 GUI 时会抛出此错误。

【问题讨论】:

    标签: python-3.x multithreading pyqt4 qthread


    【解决方案1】:

    将一个槽连接到线程的finished 信号,一旦长时间运行的任务完成,该信号就可以执行其他操作:

    class MyForm(QtGui.QMainWindow):    
        def __init__(self, parent=None):
            ...
            self.workerThread = WorkingThread()
            self.workerThread.finished.connect(self.doOtherStuff)
            ...
    
        def generateDetails(self):
            if not self.workerThread.isRunning():
                self.workerThread.start()
    
        def doOtherStuff(self):
            self.ui.lblHistory.setPixmap(QtGui.QPixmap(os.getcwd() + "/historygraph.png"))
            self.addPiechart()
            self.addWordCloud()
            self.summaryText()
    

    【讨论】:

    • 您的解决方案非常有效,过去两天一直被困在这个问题上。无论如何,一旦我关闭我的 GUI,我会抛出一个 RuntimeError,说“主线程不在主循环中”,我使用的是 QT 设计器而不是 Tkinter。如果没有任何线程部分,GUI 不会在关闭时抛出此类错误,只会挂起几秒钟
    • @rando。您是在 IDLE 中运行它还是什么?该错误显然与 PyQt 无关。尝试使用python.exe 在命令窗口中运行您的脚本。理想情况下,您的程序应该在线程关闭之前等待线程完成(或以某种方式终止它)。
    • 不,我正在使用 Pycharm 运行它
    • 根据我在stackoverflow.com/a/44598715/8373304 中发现的内容,使用队列可能会解决问题。你能指导我如何使用线程队列吗?
    • @rando。 PyQt 确实不可能引发该错误。您必须在某处运行一些 tkinter 代码 - 我可以从您问题中的代码中看到的唯一地方是 BigramsClassifier 函数。注释掉该行并输入time.sleep(2),然后重试。
    猜你喜欢
    • 1970-01-01
    • 2018-10-10
    • 2016-02-05
    • 1970-01-01
    • 2016-09-12
    • 2021-05-29
    相关资源
    最近更新 更多