J'ai un script qui a un écran de connexion et si le bouton d'annulation est enfoncé, je veux quitter l'application complètement. J'ai essayé 3 façons:
Seul le numéro 1 fonctionne. Les deux autres font que la boîte de dialogue est blanche et qu'elle clignote, puis se bloque et je ne peux même pas passer à d'autres applications. Mon code est ci-dessous:
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_())
Appeler QCoreApplication.quit()
est identique à appeler QCoreApplication.exit(0)
. Pour citer les qt docs :
Après l’appel de cette fonction, l’application quitte le fichier principal boucle d'événement et retourne de l'appel à exec (). La fonction exec () retourne returnCode. Si la boucle d'événement n'est pas en cours d'exécution, cette fonction ne fait rien. [emphase ajoutée]
Donc quit()
ou exit()
ne ressemble en rien à sys.exit()
. Ce dernier mettra fin au programme, mais le premier mettra simplement fin à la boucle d'événement (si elle est en cours d'exécution).
Lorsque l'utilisateur annule la boîte de dialogue de connexion, votre exemple doit simplement appeler sys.exit()
pour mettre fin au programme. Sinon, votre programme restera bloqué dans la boucle en bloquant.
Au lieu d'utiliser QApplication.quit()
, puisque vous avez défini app = QApplication(sys.argv)
, vous pouvez simplement écrire app.quit()
, et cela devrait fonctionner!
Quelque chose de différent mais qui pourrait être utile: je pense que ce serait plus facile si vous plaçiez la vérification de connexion au début de la fonction __init__
de votre classe Ci_Co
. De cette façon, vous commencerez par Ci_Co
au début, mais cela engendrera d'abord la classe Login
. Si la connexion échoue, vous pouvez appeler app.quit()
. S'il réussit, il passera automatiquement en Ci_Co
. Cela vous évite beaucoup de choses que vous devez écrire dans la clause if __== "__main__"
. Veuillez commenter si vous avez d'autres questions, j'ai un projet similaire avec une boîte de dialogue de connexion.