Собственно решил побаловаться с потоками в PyQt5. Придумал небольшую учебную задачку для себя по данной теме.
Форма авторизации для MySql. Всё стандартно: user - password в QLineEdit, кнопки “connect”, “disconnect” и QLabel сообщающая о статусе соединения. Форма должна проверять возможность соединения с сервером 1 раз в 3 секунды. Для этого я в метод run() класса QThread поместил соединение с БД.
#!/usr/bin/python3 # -*- coding:utf-8 -*- import sys import UI_MainForm from PyQt5.QtWidgets import * from PyQt5.QtGui import * from PyQt5.QtCore import * from PyQt5.QtSql import * class MyThread(QThread): mysignal = pyqtSignal(str) def __init__(self, _user=None, _passwd=None, parent=None): self.user = _user self.passwd = _passwd QThread.__init__(self, parent) def run(self): while True: self.sleep(3) db = QSqlDatabase.addDatabase('QMYSQL') db.setHostName('localhost') db.setDatabaseName('testbase') db.setUserName(self.user) db.setPassword(self.passwd) ok = db.open() if ok: self.mysignal.emit('ok') print('Debug: Connection: Ok') db.close() else: self.mysignal.emit('failed') print('Debug: Connection: Failed ' + db.lastError().text()) class MainForm(QMainWindow, UI_MainForm.Ui_MainWindow): def __init__(self): QMainWindow.__init__(self) self.setupUi(self) self.mythread = MyThread() self.pushButton_quit.clicked.connect(qApp.quit) self.pushButton_connect.clicked.connect(self.connect_db) self.pushButton_disconnect.clicked.connect(self.disconnect_db) self.pushButton_connect.clicked.connect(self.start_thread) self.mythread.mysignal.connect(self.change_label_conn_status, Qt.QueuedConnection) def connect_db(self): db = QSqlDatabase.addDatabase('QMYSQL') db.setHostName('localhost') db.setDatabaseName('testbase') db.setUserName(self.lineEdit_user.text()) db.setPassword(self.lineEdit_passwd.text()) ok = db.open() if ok: self.label_connection_status.setText('Connection status: Ok') QMessageBox.information(self, 'Information', 'Successful database connection') else: self.label_connection_status.setText('Connection status: Failed') QMessageBox.critical(self, 'ERROR!', 'No database connection!') def disconnect_db(self): self.pushButton_connect.setEnabled(True) self.lineEdit_user.setEnabled(True) self.lineEdit_passwd.setEnabled(True) self.lineEdit_user.clear() self.lineEdit_passwd.clear() self.lineEdit_user.setFocus() def change_label_conn_status(self, s): self.label_connection_status.setText('Connection status: ' + s) #текст не меняется def start_thread(self): self.pushButton_connect.setEnabled(False) self.lineEdit_user.setEnabled(False) self.lineEdit_passwd.setEnabled(False) self.mythread = MyThread(self.lineEdit_user.text(), self.lineEdit_passwd.text()) self.mythread.start() if __name__ == '__main__': app = QApplication(sys.argv) win = MainForm() win.show() sys.exit(app.exec_())
1. При дауне MySql, label_connection_status не изменяется на “failed”, хотя в консоль метод run() гадит print('Debug: Connection: Failed ' + db.lastError().text()), как и было задумано. Почему?
2. Два потока (в конструкторе и в методе start_thread) - бред. Как избавиться от этого бреда? Как сделать правильно?
3. Может быть можно как-то иначе реализовать проверку доступности MySql для соединения?
Заранее благодарю.