2016-05-11 4 views
0

я решил мою проблему, перемещая mySubQThreadrun() в myQThreadrun()PySide передачи сигналов от QThread к слоту в другом QThread

что сказали, я все еще хотел бы знать, почему то, что я пытался до того Жду» т работы.

Я довольно новичок в нарезке. Я сталкиваюсь с этой проблемой, и я думаю, что, возможно, я все время ошибаюсь. Я открыт для другого подхода. Я знаю, что это может быть немного запутанным.

У меня есть графический интерфейс пользователя, что делает новый полученный QThread позволяет называть его myQThread внутри этого потока, я бег через процесс, который создает другой поток называют это mySubQThread вопрос я имею следующий образ, у меня есть сигналы, определенный в моем Например, GUI: signalA = QtCore.Signal(int) и слот в myQThread Слот в mySubQThread никогда не получает сигнал.

Настоящий рабочий пример. (Несколько изменено)

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_()) 

Вот некоторый пример вывод:

Обратите внимание, что если вы измените строку:

 self.subThread = mySubQThread(parent=self) 

к

 self.subThread = mySubQThread(parent=None) 

он перестает жаловаться, как это делает в образце. ни показывает, что это делает его 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! 
+1

Проверьте документы: http://doc.qt.io/qt-4.8/qthread.html#details чуть ниже примера «WorkerThread». Это дает еще несколько объяснений тому, почему слоты в QThreads не работают, как можно было бы ожидать. – sebastian

+0

@sebastian Спасибо! Я читал это пару раз раньше, теперь это имеет больше смысла. –

+0

Теперь я убежден в использовании рабочей модели. –

ответ

2

Проблема в том, что вы переопределены QThread.run(). Метод run по умолчанию содержит реализацию, которая обрабатывает обработку сигнала.

Если вы хотите использовать сигналы/слоты правильно, вы должны создать подкласс QObject, поместить свой код в метод там, и использовать moveToThread() для перемещения QObject к базовому экземпляру QThread, что вы создать экземпляр. Вы можете запустить свой код, подключив метод к QThread.started сигнала и последующего вызова thread.start()

Вы можете повторить создание дочернего потока таким же образом, поместив этот код в способе QObject ранее созданного и запущен в поток. Сигналы и слоты, которые вы там подключаете, будут правильно выполнены между потоком и дочерним потоком.

This - хороший пример правильной связи между основной резьбой и QThread, но вы можете легко расширить ее до QThreads. Просто измените метод MyWorker.firstWork(), чтобы запустить новый QThread, как это уже сделано в методе setupThread.

+1

Теперь я полностью убежден в использовании рабочей модели. –