PySide:以新语法从QThread发出信号

时间:2016-05-18 01:32:20

标签: python pyside qthread

我正在尝试(并且正在研究)从一个工作的Qthread向主窗口发出信号,但收效甚微。我似乎不明白我应该如何在新语法中解决这个问题。

这是一个简单的例子。

from PySide.QtCore import *
from PySide.QtGui import *
import sys
import time

class Dialog(QDialog):

    def __init__(self, parent=None):
        super(Dialog, self).__init__(parent)

        button = QPushButton("Test me!")

        layout = QVBoxLayout()
        layout.addWidget(button)
        self.setLayout(layout)

        #self.button.clicked.connect(self.test) ----> 'Dialog' object has no attribute 'button'
        self.connect(button, SIGNAL('clicked()'), self.test)
        self.workerThread = WorkerThread()


    def test(self):
        self.workerThread.start()
        QMessageBox.information(self, 'Done!', 'Done.')


class WorkerThread(QThread):

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

    def run(self):
        time.sleep(5)
        print "Thread done!"


app = QApplication(sys.argv)
dialog = Dialog()
dialog.show()
app.exec_()

据我所知,如果我没有其他线程,我会在Dialog类中创建信号并将其连接到__init__但是如何创建可以从WorkerThread发出的自定义信号并且用过test()?

作为一个附带问题。您可以看到它在代码中注释了用于连接信号错误的新语法。这是我的配置吗?

我正在使用OsX El Capitan,Python 2.7

非常感谢任何帮助!非常感谢

TL:DR:我想在5秒后从WorkerThread发出一个信号,这样只有在使用新语法完成WorkingThread后,测试函数才会显示QMessageBox。

1 个答案:

答案 0 :(得分:1)

好的,这是漫长的一天,试图解决这个问题。我的主要资源是:http://www.matteomattei.com/pyside-signals-and-slots-with-qthread-example/

在新语法中,为了处理来自不同线程的信号,您必须为信号创建一个类,如下所示:

class WorkerThreadSignal(QObject):
    workerThreadDone = Signal()

这就是WorkerThread最终的样子:

class WorkerThread(QThread):

    def __init__(self, parent=None):
        super(WorkerThread, self).__init__(parent)
        self.workerThreadSignal = WorkerThreadSignal()

    def run(self):
        time.sleep(3)
        self.workerThreadSignal.workerThreadDone.emit()

对于Dialog类的连接:

    self.workerThread = WorkerThread()
    self.buttonn.clicked.connect(self.test)

    self.workerThreadSignal = WorkerThreadSignal()
    self.workerThread.workerThreadSignal.workerThreadDone.connect(self.success)

def success(self):
    QMessageBox.warning(self, 'Warning!', 'Thread executed to completion!')

因此,一旦发出信号,就会调用成功方法。

我花了最长的时间来弄清楚最后一行代码。我原本以为我可以直接连接到WorkerThreadSignal类,但至少在这种情况下,它只有在我回溯它的位置时才能工作。从Dialog init 到WorkerThread init 返回WorkerThreadSignal。我从上面提到的网站上提取了这个提示。

我觉得很奇怪,我必须在两个类上创建相同的局部变量,也许有一种方法来创建一个全局变量,我可以参考所有当前的解决方案,但它现在可以工作。

我希望这有助于某人也坚持这个过程!

PS:连接的语法问题也已解决。所以一切都是用新语法编写的,这很棒。