2016-07-09 3 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-loop.

1

Вместо использования QApplication.quit(), так как вы определили app = QApplication(sys.argv), вы могли бы просто написать app.quit(), и это должно работать!

Нечто несвязанное, но может быть полезно: я думаю, было бы проще, если бы вы положили регистрационную проверку в начале функции __init__ вашего класса Ci_Co. Таким образом, вы начнете Ci_Co в начале, но сначала он будет порождать класс Login. Если логин завершается с ошибкой, вы можете позвонить app.quit(), и если он преуспеет, он автоматически перейдет в Ci_Co. Это избавит вас от многих вещей, которые вы должны написать в предложении if __name__ == "__main__". Прокомментируйте, если у вас есть еще вопросы, у меня есть аналогичный проект с диалоговым окном входа.

+0

Вы абсолютно правы в использовании app.quit(). Тем не менее, это дает мне то же самое замораживание в диалоговом окне в Windows 10. Я запускал программу в Linux Mint, и она застыла в графическом интерфейсе, но я смог войти в терминал и обнаружил, что CPU был на 100%, поэтому кажется, что быть в какой-то петле. Итак, app..quit() не ведет себя иначе. – Dkellygb

+0

Я вижу ваш второй пункт и рассмотрю его в следующий раз, когда я реорганизую. – Dkellygb

Смежные вопросы