2016-07-09 289 views
3

我有一個腳本,它有一個登錄屏幕,如果按下取消按鈕,我想完全退出應用程序。我已經嘗試了3種方式:正確的方法來退出/退出PyQt程序

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

回答

3

致電QCoreApplication.quit()與致電QCoreApplication.exit(0)相同。從qt docs引述:此函數被調用

後,應用程序離開主 事件循環,並返回從調用exec()。 exec()函數 返回returnCode如果事件循環未運行,則此功能 不執行任何操作。 [強調]

所以quit()exit()一點不像sys.exit()。後者將終止程序,但前者將僅僅終止事件循環(如果它正在運行)。

當用戶取消登錄對話框時,您的示例應該調用sys.exit()來終止程序。否則,你的程序將會卡在阻塞的while循環中。

1

而不是使用QApplication.quit()的,因爲你定義app = QApplication(sys.argv),你可以只寫app.quit(),並應工作!

一些不相關但可能有用的東西:我認爲如果將登錄檢查放在Ci_Co類的__init__函數的開頭,會更容易。這樣,你將在開始時開始Ci_Co,但它將首先產生Login類。如果登錄失敗,您可以撥打app.quit(),如果成功,它將自動轉換爲Ci_Co。這可以使您避免在if __name__ == "__main__"子句中編寫的許多事項。如果您還有其他問題,請發表評論,我有一個類似的項目和一個登錄對話框。

+0

你對使用app.quit()絕對正確。但是,它給了我在Windows 10上的對話框相同的凍結。我運行Linux Mint上的程序,它凍結了GUI,但我能夠登錄到終端,發現CPU是100%,所以它似乎處於某種循環。所以,app..quit()沒有任何不同。 – Dkellygb

+0

我看到你的第二點,並將在下次重構時考慮它。 – Dkellygb