Скрипт потоков не заканчивается - PullRequest
0 голосов
/ 02 октября 2018

Я новичок в PyQt5.Я написал следующий код, который в идеале должен завершаться.

from PyQt5.QtCore import QCoreApplication, pyqtSignal, QObject
import sys
import thread

class MainWindow(QObject):    
    def __init__(self):
        super().__init__()
        self.myMethod()        

    def myMethod(self):
        self.myThread = thread.MainWindow(self)
        self.myThread.threadTerminate.connect(self.finished)
        self.myThread.start()

    def finished(self, arg1):
        print("Message recieved is "+arg1)
        QCoreApplication.quit()

if __name__ == '__main__':    
    qApp = QCoreApplication(sys.argv)
    w = MainWindow()
    qApp.exec_()

Код потока:

from PyQt5.QtCore import QThread, QCoreApplication, pyqtSignal
import sys
import time

class MainWindow(QThread):
    threadTerminate = pyqtSignal(bool)
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.itsOver = False

    def run(self):
        print("Hello World!")
        time.sleep(3)
        print("Alice")
        time.sleep(4)
        print("Bob")
        time.sleep(4)
        self.stop()

    def stop(self):
        print("About to terminate....")
        self.itsOver = True
        self.threadTerminate.emit(self.itsOver)
        self.terminate()  

Что я делаю не так?Есть ли способ отследить поток выполнения моей программы и узнать состояние моих переменных?

1 Ответ

0 голосов
/ 02 октября 2018

Похоже, у вас простое условие гонки.

Когда я добавляю time.sleep(1) между вызовами к self.threadTerminate.emit и self.terminate, программа завершается, как и ожидалось (за исключением вашего оператора печати, где strи bool не может быть объединен, естественно).

Не зная точных деталей того, как Qt обрабатывает поток сигналов / слотов, я бы сказал, что ваш вызов terminate очищает поток и его сигналы до того, каквызов подключенного слота в потоке MainWindow, тем самым стирая событие finished из цикла событий и пропуская ваш вызов на Quit().

Короче: выполните self.exit() вQ вместо этого.Это изящная альтернатива выключению terminate, которую, насколько я видел, вам следует избегать, когда это возможно.


В качестве примечания, возможно, переосмыслите названия модулей и классов.Модуль thread был модулем в Python2, переименован в _thread в Python3.Это сначала смутило меня (так же, как и выше), так как у вас есть собственный модуль с именем "thread.py".Кроме того, MainWindow напоминает название PyQt5.QtWidgets.QMainWindow, тогда как QCoreApplication не имеет «окон».

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...