2016-07-09 28 views
3

私はログイン画面を持つスクリプトを持っています。キャンセルボタンを押すと、アプリケーションを完全に終了します。 )QCoreApplication.instance(PyQtプログラムを終了/終了するための適切な方法

  1. sys.exit()
  2. QApplication.quit()
  3. ()

のみ数1作品を辞め:私は3つの方法を試してみました。他の2つはダイアログボックスを白くし、それが点滅してハングアップし、他のアプリケーションに切り替えることさえできません。私のコードは以下の通りです:

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

私はあなたの2番目のポイントを見て、次回私がリファクタリングするときにそれを考慮します。 – Dkellygb

関連する問題