简体   繁体   English

PySide2:不能在不退出 APP 的情况下关闭 QMessageBox

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

Here is a little code, where I have a thread connecting to a ftp server and showing message boxes.这是一个小代码,我有一个线程连接到 ftp 服务器并显示消息框。 I don't understant why, as soon as the msgBoxWait dialog is closed, the app crashed (terminates before the FTP thread).我不明白为什么只要关闭msgBoxWait对话框,应用程序就会崩溃(在 FTP 线程之前终止)。

I guess this is because it is the last window displayed, however, adding a QEventLoop doesn't fix it.我想这是因为它是最后一个显示的窗口,但是,添加 QEventLoop 并不能解决它。 Can you help me ?你能帮助我吗 ?

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

By default, Qt is configured so that if the last window is closed, the application will end because it is generally the expected behavior but that is not your case because there are times when you need to continue running even if there are no open windows.默认情况下,Qt 被配置为如果最后一个窗口关闭,应用程序将结束,因为这通常是预期的行为,但这不是您的情况,因为有时即使没有打开的窗口,您也需要继续运行。 The solution is to set the quitOnLastWindowClosed property to False:解决方案是将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