退出/退出PyQt程序的正确方法

Dke*_*ygb 10 python pyqt pyqt5

我有一个具有登录屏幕的脚本,如果按下取消按钮,我想完全退出应用程序.我试过3种方法:

  1. sys.exit()
  2. QApplication.quit()
  3. QCoreApplication.instance()退出()

只有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_())
Run Code Online (Sandbox Code Playgroud)

ekh*_*oro 13

呼叫QCoreApplication.quit()与呼叫相同QCoreApplication.exit(0).引用qt文档:

调用此函数后,应用程序将离开主事件循环并从调用返回到exec().exec()函数返回returnCode.如果事件循环未运行,则此函数不执行任何操作.[强调补充]

所以quit()或者exit()没什么sys.exit().后者将终止程序,但前者只会终止事件循环(如果它正在运行).

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


Pet*_*ang 7

由于QApplication.quit()您定义了,所以app = QApplication(sys.argv)您可以直接编写app.quit(),而不是使用 ,这应该可以工作!

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

  • 您对于使用 app.quit() 的看法是完全正确的。然而,它在 Windows 10 上的对话框上给了我同样的冻结。我在 Linux Mint 上运行该程序,它冻结了 GUI,但我能够登录到终端,发现 CPU 为 100%,所以看起来处于某种循环中。因此,app..quit() 的行为没有任何不同。 (2认同)