繁体   English   中英

PyQt5:线程未结束? 进程以退出代码 -1 结束

[英]PyQt5: Thread Not Ending? Process finished with exit code -1

下面的代码运行良好并完成了它的工作。 但是,当我退出 GUI 时,python 文件没有完成处理。

当我运行 pycharm 调试运行然后强制终止调试时,我收到消息“进程完成,退出代码 -1”。

谁能帮我找出导致此错误的原因?

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget
from pybithumb import WebSocketManager
from PyQt5.QtCore import QThread, pyqtSignal

class OverViewWorker(QThread):
    data24Sent = pyqtSignal(int, float, int, float, int, int)
    dataMidSent = pyqtSignal(int, float, float)

    def __init__(self, ticker):
        super().__init__()
        self.ticker = ticker
        self.alive = True

    def run(self):
        wm = WebSocketManager("ticker", [f"{self.ticker}_KRW"], ["24H", "MID"])
        while self.alive:
            data = wm.get()
            if data['content']['tickType'] == "MID":
                self.dataMidSent.emit(int(data['content']['closePrice']),
                    ## Deleted
            else:
                self.data24Sent.emit(int(data['content']['closePrice']),
                    ## Deleted

    def close(self):
        self.alive = False

class OverviewWidget(QWidget):
    def __init__(self, parent=None, ticker="BTC"):
        super().__init__(parent)
        uic.loadUi("resource/overview.ui", self)

        self.ticker = ticker
        self.ovw = OverViewWorker(ticker)
        self.ovw.data24Sent.connect(self.fill24Data)
        self.ovw.dataMidSent.connect(self.fillMidData)
        self.ovw.start()

    def fill24Data(self, currPrice, volume, highPrice, value, lowPrice, PrevClosePrice):
        ## Deleted

    def fillMidData(self, currPrice, chgRate, volumePower):
        ## Deleted

    def closeEvent(self, event):
        self.ovw.close()

if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    ob = OverviewWidget()
    ob.show()
    exit(app.exec_())

在您的代码中,QThread.run() 方法进入了一个 while True 循环,它永远不会允许任何 CPU 时间执行 close 方法并将 self.alive 更改为 False,因此即使您从QWidget。

然后你试图退出一个仍在运行的线程,这会给你-1返回代码,因为你的 QThread 被强行杀死而没有完成它的任务。

如果您添加从循环中更新活动参数的可能性,您可以摆脱这个问题,但它需要 QThread 来访问 QWidget 的参数,这可能不是您想要的。

此外,使用 QThread.wait() 方法可以帮助您进行同步,因为它会强制延迟 QWidget 的退出,直到 ovw 从运行返回。 由于您的 -1 返回代码可能只是由于您的 QApplication 在线程完成之前退出时刻,因此同步退出将缓解这种情况。

这是基于您的代码的示例:

from PyQt5 import uic
from PyQt5.QtWidgets import QWidget
from pybithumb import WebSocketManager
from PyQt5.QtCore import QThread, pyqtSignal

class OverViewWorker(QThread):
    data24Sent = pyqtSignal(int, float, int, float, int, int)
    dataMidSent = pyqtSignal(int, float, float)

    def __init__(self, ticker, master):
        super().__init__()
        self.ticker = ticker
        self.master = master
        self.alive = True

    def run(self):
        wm = WebSocketManager("ticker", [f"{self.ticker}_KRW"], ["24H", "MID"])
        while self.alive:
            data = wm.get()
            if data['content']['tickType'] == "MID":
                self.dataMidSent.emit(int(data['content']['closePrice']),
                    ## Deleted
            else:
                self.data24Sent.emit(int(data['content']['closePrice']),
                    ## Deleted

            self.get_alive_from_master()

        # Do here anything you want in the thread before quitting.

    def get_alive_from_master(self):
        self.alive = master.ovw_alive

class OverviewWidget(QWidget):
    def __init__(self, parent=None, ticker="BTC"):
        super().__init__(parent)
        uic.loadUi("resource/overview.ui", self)

        self.ticker = ticker
        self.ovw = OverViewWorker(ticker, self)
        self.ovw.data24Sent.connect(self.fill24Data)
        self.ovw.dataMidSent.connect(self.fillMidData)
        self.ovw_alive = True
        self.ovw.start()

    def fill24Data(self, currPrice, volume, highPrice, value, lowPrice, PrevClosePrice):
        ## Deleted

    def fillMidData(self, currPrice, chgRate, volumePower):
        ## Deleted

    def closeEvent(self, event):
        self.ovw_alive = False
        self.ovw.wait()

if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication
    app = QApplication(sys.argv)
    ob = OverviewWidget()
    ob.show()
    exit(app.exec_())

如果最后一个 window 关闭,则 Qt 应用程序退出,如果还有正在运行的线程,则终止它们。 它可以被app.setQuitOnLastWindowClosed(False)覆盖。 在这种情况下,您必须在线程finished时调用app.quit()以终止应用程序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM