簡體   English   中英

PySide2:不能在不退出 APP 的情況下關閉 QMessageBox

[英]PySide2 : cannot close a QMessageBox without quitting the APP

這是一個小代碼,我有一個線程連接到 ftp 服務器並顯示消息框。 我不明白為什么只要關閉msgBoxWait對話框,應用程序就會崩潰(在 FTP 線程之前終止)。

我想這是因為它是最后一個顯示的窗口,但是,添加 QEventLoop 並不能解決它。 你能幫助我嗎 ?

# coding: utf-8

import sys
import random
from PySide2 import QtCore, QtWidgets, QtGui


class Logic():
    def __init__(self):
        self.msgBoxWait = QtWidgets.QMessageBox()
        self.ftpThread = FtpThread()
        self.isConnected = False
        self.loop = QtCore.QEventLoop()

    def run(self):
        self.ftpThread.sigIsConnected.connect(self.ftpConnected, QtCore.Qt.QueuedConnection)
        self.ftpThread.finished.connect(self.ftpFinished, QtCore.Qt.QueuedConnection)
        self.ftpThread.sigError.connect(self.ftpError, QtCore.Qt.QueuedConnection)
        self.ftpThread.start()

        QtCore.QTimer.singleShot(200, self.showWaitMsgBox)

        self.loop.exec_()

    def showWaitMsgBox(self):
        self.msgBoxWait.setWindowTitle("Waiting")
        self.msgBoxWait.setText("""Waiting for ftp connection""")
        if not self.isConnected:
            self.msgBoxWait.exec()

    def ftpConnected(self):
        print("connected")
        self.isConnected = True
        self.msgBoxWait.close()  # <- crash here or when I click on the close button

    def ftpFinished(self):
        print("finished")
        self.ftpThread = None
        self.loop.quit()

    def ftpError(self, title, message):
        QtWidgets.QMessageBox.critical(None, title, message)


class FtpThread(QtCore.QThread):
    sigIsConnected = QtCore.Signal()
    sigError = QtCore.Signal(str, str)

    def run(self):
        QtCore.QThread.sleep(2)
        self.sigIsConnected.emit()
        QtCore.QThread.sleep(1)
        self.sigError.emit("error", "An error appened")
        QtCore.QThread.sleep(3)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])

    logic = Logic()
    QtCore.QTimer.singleShot(0, logic.run)

    sys.exit(app.exec_())

默認情況下,Qt 被配置為如果最后一個窗口關閉,應用程序將結束,因為這通常是預期的行為,但這不是您的情況,因為有時即使沒有打開的窗口,您也需要繼續運行。 解決方案是將quitOnLastWindowClosed屬性設置為 False:

# coding: utf-8

import sys
import random
from PySide2 import QtCore, QtWidgets, QtGui


class Logic:
    def __init__(self):
        self.msgBoxWait = QtWidgets.QMessageBox()
        self.ftpThread = FtpThread()
        self.isConnected = False

    def run(self):
        self.ftpThread.sigIsConnected.connect(
            self.ftpConnected, QtCore.Qt.QueuedConnection
        )
        self.ftpThread.finished.connect(self.ftpFinished, QtCore.Qt.QueuedConnection)
        self.ftpThread.sigError.connect(self.ftpError, QtCore.Qt.QueuedConnection)
        self.ftpThread.start()

        QtCore.QTimer.singleShot(200, self.showWaitMsgBox)

    def showWaitMsgBox(self):
        self.msgBoxWait.setWindowTitle("Waiting")
        self.msgBoxWait.setText("""Waiting for ftp connection""")
        if not self.isConnected:
            self.msgBoxWait.exec()

    def ftpConnected(self):
        print("connected")
        self.isConnected = True
        self.msgBoxWait.close()

    def ftpFinished(self):
        print("finished")
        self.ftpThread = None
        # QtCore.QCoreApplication.quit() should be used # to close the entire application if necessary QtCore.QCoreApplication.quit()

    def ftpError(self, title, message):
        QtWidgets.QMessageBox.critical(None, title, message)


class FtpThread(QtCore.QThread):
    sigIsConnected = QtCore.Signal()
    sigError = QtCore.Signal(str, str)

    def run(self):
        QtCore.QThread.sleep(2)
        self.sigIsConnected.emit()
        QtCore.QThread.sleep(1)
        self.sigError.emit("error", "An error appened")
        QtCore.QThread.sleep(3)


if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    app.setQuitOnLastWindowClosed(False)

    logic = Logic()
    QtCore.QTimer.singleShot(0, logic.run)

    sys.exit(app.exec_())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM