与QThreads沟通

时间:2014-07-24 09:17:37

标签: multithreading qt pyqt qthread

现在(仅为了解释)Main.process()函数和WorkerThread.run()函数是相同的。 它们通过从listWidget获取Main布局中的值来操作。 我希望我的workerthread类使用我在主列表小部件上设置的参数。

import sys, time
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class Main(QWidget):
    def __init__(self, parent = None):
        super(Main, self).__init__()

        self.trdprocessbtn = QPushButton("Thread Processing")
        self.guiprocessbtn = QPushButton("Main Processing")

        self.listwidget = QListWidget()
        for i in range(10):
            self.listwidget.addItem(str(i))

        layout = QVBoxLayout()
        layout.addWidget(self.listwidget)
        layout.addWidget(self.guiprocessbtn)
        layout.addWidget(self.trdprocessbtn)
        self.setLayout(layout)

        self.guiprocessbtn.clicked.connect(self.process)

        self.workerthread = WorkerThread()
        self.trdprocessbtn.clicked.connect(self.startthread)

    def startthread(self):
        self.workerthread.start()

    def process(self):
        x = self.listwidget.currentItem().text()
        for i in range(int(x)):
            print "this is main processing ", i 
            time.sleep(1)

    def dialogOpen(self):
        dialog = Dialog()
        dialog.exec_()

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

    def run(self):
        x = self.listwidget.currentItem().text()
        for i in range(int(x)):
            print "This is thread processing ", i 
            time.sleep(1) 


app = QApplication(sys.argv)
form = Main()
form.show()
app.exec_()

1 个答案:

答案 0 :(得分:1)

x = self.listwidget.currentItem().text()方法中的第run行很糟糕。您只能从主/ GUI线程访问小部件。

另一件事是,你的process插槽阻塞了!永远不要阻止主线程(如果你阻止另一个线程,如果你不确定你做得对,你可能会做错了。)

一个简短的修复列表:

  • 删除线程的run方法,让Qt事件循环也在线程中运行。

  • QListWidget::currentTextChanged(const QString & currentText)信号连接到线程和主类中的新插槽,然后使该插槽启动/更新下一个提到的计时器和计数器。

  • 使用QTimer替换阻塞循环,将timeout信号连接到一个插槽,该插槽执行您现在在循环中执行的操作。由于您睡眠1秒钟,您应该将计时器设置为每秒关闭一次。由于您只想运行一些设定的次数,所以将计数器变量添加到您的类中,并跟踪超时发生的次数,并在完成时关闭计时器。

  • 如果您需要更复杂的列表数据处理,请在主类中为此创建一个插槽,并将相应的QListWidget信号连接到它。然后向主类添加一个信号,其中包含线程的已处理数据,您将从此插槽中发出该数据。最后,为线程添加匹配槽,以处理线程中由您自己的信号发送的数据。你需要这样做,因为(我认为)只访问QListWidget的数据也不是线程安全的。