PySide将信号从QThread传递到另一个QThread中的插槽 [英] PySide passing signals from QThread to a slot in another QThread

查看:141
本文介绍了PySide将信号从QThread传递到另一个QThread中的插槽的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我通过将mySubQThread run()移到myQThread run()

那就是说,我仍然想知道为什么以前我尝试过的东西不起作用.

That said, I still would like to know why what I was attempting before didn't work.

我对线程很陌生.我遇到了这个问题,我想无论如何都会出错.我对其他方法持开放态度,我知道这可能会让人有些费解.

I'm pretty new to threading. I am running into this issue and I think I may be approaching things wrong, anyway here goes. I am open to a different approach I know this may be a bit convoluted to follow.

我有一个使新派生的QThread可以在该线程中称为myQThread的GUI,我正在运行一个创建另一个线程并将其称为mySubQThread的进程,我遇到的问题如下,我在我的GUI中定义了信号,例如:signalA = QtCore.Signal(int)myQThread中的插槽.mySubQThread中的插槽似乎从未收到信号.

I have a GUI that makes a new derived QThread lets call it myQThread within that thread, I am running through a process that creates another thread call it mySubQThread the issue I am having is as follows, I have signals defined in my GUI for example: signalA = QtCore.Signal(int) and a slot in myQThread The slot in the mySubQThread never seems to get the signal.

这是一个可行的示例. (稍作修改)

Here is a working example. (modified somewhat)

from PySide import QtCore, QtGui
import time



class myQThread(QtCore.QThread):
    myThreadSignal = QtCore.Signal(int)
    def __init__(self, parent):
        super(myQThread, self).__init__(parent=parent)

    def run(self):
        self.subThread = mySubQThread(parent=self)
        self.myThreadSignal.connect(self.subThread.sub_thread_slot)
        self.myThreadSignal.connect(self.test_slot)
        print "starting subthread..."
        self.subThread.start()

        while self.subThread.isRunning():
            print "myQThread is alive!"
            time.sleep(1)
        print "myQThread exiting run..."
    @QtCore.Slot(int)
    def my_thread_slot(self, a):
        print "1b) Made it here!"
        self.myThreadSignal.emit(a)

    @QtCore.Slot(int)
    def test_slot(self, a):
        print "2a) Made it here!"

class mySubQThread(QtCore.QThread):
    mySubSignalA = QtCore.Signal(int)
    def __init__(self, parent):
        super(mySubQThread, self).__init__(parent=parent)
        self._abort = False
    def run(self):
        #Do some processing
        #Wait for signal
        self._abort = False
        while not self._abort:
            print "mySubQThread is alive!"
            time.sleep(1)
        print "mySubQThread exiting run..."

    @QtCore.Slot(int)
    def sub_thread_slot(self, a):
        print "2b)Never make it here!"
        self._abort = True


class myWidget(QtGui.QWidget):
    myWidgetSignal = QtCore.Signal(int)
    def __init__(self, parent=None):
        super(myWidget, self).__init__(parent=parent)
        #simple Widget to test this out....
        myLayout = QtGui.QVBoxLayout()
        self.runButton = QtGui.QPushButton("run")
        self.runButton.clicked.connect(self.run_button_pressed)

        self.otherButton = QtGui.QPushButton("other")
        self.otherButton.clicked.connect(self.other_button_pressed)

        myLayout.addWidget(self.runButton)
        myLayout.addWidget(self.otherButton)

        self.setLayout(myLayout)
    @QtCore.Slot()
    def run_button_pressed(self):
        self.processThread = myQThread(self)
        self.myWidgetSignal.connect(self.processThread.my_thread_slot)
        self.myWidgetSignal.connect(self.test_slot)
        self.processThread.start()
    @QtCore.Slot()
    def other_button_pressed(self):
        self.myWidgetSignal.emit(1)

    @QtCore.Slot(int)
    def test_slot(self, a):
        print "1a) Made it here!"

if __name__ == "__main__":
    import sys
    myApp = QtGui.QApplication(sys.argv)
    myWin = myWidget()
    myWin.show()
    sys.exit(myApp.exec_())

以下是一些示例输出:

请注意,如果您更改行:

Note that if you change the line:

        self.subThread = mySubQThread(parent=self)

        self.subThread = mySubQThread(parent=None)

它不再像在示例输出中那样抱怨.都没有表明它达到了2B

it stops complaining as it does in the sample output. neither shows that it makes it to 2B

QObject: Cannot create children for a parent that is in a different thread.
(Parent is myQThread(0x3c3faf0), parent's thread is QThread(0x2792548), current thread is myQThread(0x3c3faf0)
starting subthread...
myQThread is alive!mySubQThread is alive!

mySubQThread is alive!
myQThread is alive!
1b) Made it here!
2a) Made it here!
1a) Made it here!

推荐答案

问题是因为您已覆盖QThread.run().默认情况下,run方法包含一个处理信号处理的实现.

The problem is because you have overridden QThread.run(). The run method by default contains an implementation that handles signal processing.

如果要正确使用信号/插槽,则应子类化QObject,将代码放在其中的方法中,然后使用moveToThread()QObject移至实例化的QThread的基本实例.然后,可以通过将方法连接到QThread.started信号,然后调用thread.start()

If you want to use signals/slots correctly you should subclass QObject, put your code in a method in there, and use moveToThread() to move the QObject to a base instance of QThread that you instantiate. You can then run your code by connecting your method to the QThread.started signal and then calling thread.start()

然后,您可以通过将代码放入先前在线程中创建并启动的QObject的方法中,以类似的方式重复子线程的创建.您在其中连接的信号和插槽将在线程与其子线程之间正确显示.

You can then repeat the creation of the child thread in a similar way, by putting that code in the method of the QObject previously created and launched in the thread. Signals and slots you connect there will be made between the thread and it's child thread correctly.

是主线程和QThread之间正确通信的一个很好的例子,但是您可以轻松扩展它在QThreads之间.只需修改MyWorker.firstWork()方法以启动新的QThread,就像setupThread方法中已经完成的那样.

This is a good example of proper communication between the main thread and a QThread, but you could easily extend it to between QThreads. Just modify the MyWorker.firstWork() method to launch a new QThread like is already done in the setupThread method.

这篇关于PySide将信号从QThread传递到另一个QThread中的插槽的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆