Поток Python QT5 не обновляет элементы управления в режиме реального времени
Я пишу пользовательский интерфейс с использованием QT5 и Python, я добавил поток для обработки пользовательского интерфейса, поток работает "отлично", функция внутри потока получает 2 строки и возвращает 2 строки (я делаю эксперименты, прежде чем разрабатывать реальный проект просто чтобы увидеть, как это работает), как вы можете видеть в коде после вызова функции потока с помощью:
self.requestConexion.emit('lblText1','dddddd')
Я вызываю другую функцию, которая просто счетчик
self.contador()
поэтому я ожидаю, что до того, как счетчик завершит работу, значение элемента self.lblText1 изменится, но этого не происходит... вот основной код:
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
import UI_test
import time
import sys
class Threaded(QObject):
result=pyqtSignal(str,str)
def __init__(self, parent=None, **kwargs):
super().__init__(parent, **kwargs)
@pyqtSlot(str,str)
def etiquetas(self,lbl,texto):
print(texto)
self.result.emit(lbl,texto)
class MainApp(QMainWindow, UI_test.Ui_MainWindow):
requestConexion=pyqtSignal(str,str)
def __init__(self, parent=None):
super(MainApp, self).__init__(parent)
self._thread=QThread()
self._threaded=Threaded(result=self.displayLabel)
self.requestConexion.connect(self._threaded.etiquetas)
self._threaded.moveToThread(self._thread)
qApp.aboutToQuit.connect(self._thread.quit)
self._thread.start()
self.setupUi(self)
self.btnStart.clicked.connect(self.conexion)
@pyqtSlot()
def conexion(self):
#self._thread.start()
print(1)
self.requestConexion.emit('lblText1','dddddd')
self.contador()
text, ok = QInputDialog.getText(self, 'Text Input Dialog', 'Enter your name:')
if ok:
print(str(text))
@pyqtSlot()
def contador(self):
i=0
while i<50:
print(i)
time.sleep(0.1)
i+=1
@pyqtSlot(str,str)
def displayLabel(self, etiqueta, texto):
self.lblText1.setText(etiqueta)
print(texto)
def main():
app = QApplication(sys.argv)
form = MainApp()
form.show()
app.exec_()
exit(app.exec_())
if __name__ == '__main__':
main()
Любая идея, что не так?
1 ответ
Я наконец-то нашел ответ на свой вопрос в следующем блоге:
https://martinfitzpatrick.name/article/multithreading-pyqt-applications-with-qthreadpool/
это действительно хороший урок, после прочтения документации в блоге я смог изменить один из примеров, чтобы изменить текст элемента управления меткой в режиме реального времени; вот окончательный код:
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
import time
class Worker(QRunnable):
def __init__(self, fn, *args, **kwargs):
super(Worker, self).__init__()
self.args = args
self.kwargs = kwargs
self.fn = fn
@pyqtSlot()
def run(self):
#print(self.args, self.kwargs)
print("Thread start")
time.sleep(0.2)
self.fn(*self.args, **self.kwargs) #ejecuta la funcion recibida
class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs):
super(MainWindow, self).__init__(*args, **kwargs)
self.threadpool = QThreadPool()
print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())
self.counter = 0
layout = QVBoxLayout()
self.l = QLabel("Start")
self.l2 = QLabel("xxxxx")
b = QPushButton("DANGER!")
b.pressed.connect(self.oh_no)
layout.addWidget(self.l)
layout.addWidget(self.l2)
layout.addWidget(b)
w = QWidget()
w.setLayout(layout)
self.setCentralWidget(w)
self.show()
self.etiqueta="rrrrrrrrrr"
self.timer = QTimer()
self.timer.setInterval(500)
self.timer.timeout.connect(self.recurring_timer)
self.timer.start()
def oh_no(self):
self.etiqueta="hhhhhhhhhhhhhhhhh"
worker = Worker(self.execute_this_fn,'4444')
self.threadpool.start(worker)
def recurring_timer(self):
self.counter +=1
self.l.setText("Counter: %d" % self.counter)
def execute_this_fn(self,x):
print("Hello!")
self.l2.setText(x)
app = QApplication([])
window = MainWindow()
app.exec_()