退出PyQt程序的正确方法

2024-06-14 02:42:13 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个脚本,其中有一个登录屏幕,如果取消按钮被按下,我想退出整个应用程序。我试过三种方法:

  1. 系统退出()
  2. QApplication.quit()
  3. QCoreApplication.instance().quit()

只有1号有效。另外两个使对话框变为白色,它闪烁然后挂起,我甚至不能切换到其他应用程序。我的代码如下:

from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtSql import *
from PyQt5.QtWidgets import *


import csv
import sys
from datetime import datetime, timedelta, time
import os

from ci_co_table import *
from login import *

class Ci_Co(QMainWindow):
    """Check in and check out module"""

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

class Login(QDialog):
    """User login """
    def __init__(self):
        QDialog.__init__(self)
        self.ui = Ui_login_form()
        self.ui.setupUi(self)
        self.ui.buttonBox.accepted.connect(lambda: self.handle_login(servers=servers))
        servers = {}
        with open('servers.csv', newline='') as csvfile:
            server_reader = csv.reader(csvfile)
            for row in server_reader:
                self.ui.cbo_db_name.addItem(row[1])
                servers[row[1]] = (row[0],row[2])

    def handle_login(self, servers=''):
        global user
        global pword
        global database
        global server
        global bg_colour
        user = self.ui.username.text()
        pword = self.ui.password.text()
        database = self.ui.cbo_db_name.currentText()
        server = servers[database][0]
        bg_colour = servers[database][1]


if __name__=="__main__":
    app=QApplication(sys.argv)
    global hotdate
    global hotdate_string
    global folio_num
    global user
    global pword
    global dbase
    global server
    pword = ""
    global database
    global bg_colour
    #Login
    while True:
        if Login().exec_() == QDialog.Accepted:
            db = QSqlDatabase.addDatabase("QPSQL");
            db.setHostName(server)
            db.setDatabaseName(database);
            db.setUserName(user);
            db.setPassword(pword)
            if (db.open()==False):     
                QMessageBox.critical(None, "Database Error", db.lastError().text())
            else:
                break
        else:
            #QApplication.quit()
            QCoreApplication.instance().quit()            
            #sys.exit()


    myapp = Ci_Co()
    myapp.show()
    sys.exit(app.exec_())

Tags: fromimportselfuidbserversyslogin
2条回答

因为您定义了app = QApplication(sys.argv),所以您可以只编写app.quit(),而不使用QApplication.quit(),这应该是可行的!

一些不相关但可能有用的东西:我认为如果您将登录检查放在__init__类的Ci_Co函数的开头会更容易。这样,您将在开始时启动Ci_Co,但它将首先生成Login类。如果登录失败,您可以调用app.quit(),如果成功,它将自动转换为Ci_Co。这就省去了您必须在if __name__ == "__main__"子句中编写的许多内容。请评论如果你还有任何问题,我有一个类似的项目与登录对话框。

调用QCoreApplication.quit()与调用QCoreApplication.exit(0)相同。引用qt docs

After this function has been called, the application leaves the main event loop and returns from the call to exec(). The exec() function returns returnCode. If the event loop is not running, this function does nothing. [emphasis added]

所以quit()exit()sys.exit()完全不同。后者将终止程序,但前者仅终止事件循环(如果它正在运行)。

当用户取消登录对话框时,您的示例应该只调用sys.exit()来终止程序。否则,您的程序将陷入阻塞while循环。

相关问题 更多 >