簡體   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