简体   繁体   English

使用线程时PyQt5中没有更新GUI

[英]No update GUI in PyQt5 When I use threads

I read the information about temperature and voltage from a controller with Modbus Lib. 我从带有Modbus Lib的控制器中读取了有关温度和电压的信息。 When I do this in a "try ... except", everything works fine. 当我以“尝试...除外”方式进行操作时,一切正常。 But when I do this in a while loop with the Thread, the GUI stays constant for about 20 seconds. 但是,当我使用线程在while循环中执行此操作时,GUI会保持恒定约20秒。 However, the temperature printing is working properly. 但是,温度打印工作正常。 Then, when I click the button on the GUI, the GUI information is updated. 然后,当我单击GUI上的按钮时,GUI信息将更新。

from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.QtWidgets import QApplication
import time
from modbusFunction import *

First Code With Try except & second Code With While Loop And Threading: 除try之外的第一个代码,以及while循环和线程化的第二个代码:

class test(QtWidgets.QMainWindow):
    def __init__(self):
        super(test, self).__init__()
        uic.loadUi('ui/test.ui', self)
        self.readTemp()

    def readTemp(self):
        try:
            temp = modbusFunction.modbusReadRegister(self, '192.168.1.13', 502, 0x1192, 1)
            print(temp[0])
            self.supplyTempResualt.setText(str(temp[0]))
        except Exception as err:
            print(err)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = test()
    window.show()
    sys.exit(app.exec_())

The second Code: 第二个代码:

from threading import Thread

class test(QtWidgets.QMainWindow):
    def __init__(self):
        super(test, self).__init__()
        uic.loadUi('ui/test.ui', self)

        t = Thread(target = self.readTemp)
        t.daemon = True
        t.start()

    def readTemp(self):
        while True:
            try:
                temp = modbusFunction.modbusReadRegister(self, '192.168.1.13', 502, 0x1192, 1)
                print(temp[0])
                self.supplyTempResualt.setText(str(temp[0]))
            except Exception as err:
                print(err)
            time.sleep(1)


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = test()
    window.show()
    sys.exit(app.exec_())

You should not update the GUI directly from another thread, to update there are the following methods: 您不应该直接从另一个线程更新GUI,要更新有以下方法:

1. pyqtSignal() 1. pyqtSignal()

class test(QtWidgets.QMainWindow):
    textChanged = QtCore.pyqtSignal()

    def __init__(self):
        super(test, self).__init__()
        uic.loadUi('ui/test.ui', self)
        self.textChanged.connect(self.supplyTempResualt.setText)

        t = Thread(target = self.readTemp)
        t.daemon = True
        t.start()

    def readTemp(self):
        while True:
            try:
                temp = modbusFunction.modbusReadRegister(self, '192.168.1.13', 502, 0x1192, 1)
                print(temp[0])
                self.textChanged.emit(str(temp[0]))
            except Exception as err:
                print(err)
            time.sleep(1)

2. QMetaObject::invokeMethod 2. QMetaObject :: invokeMethod

def readTemp(self):
    while True:
        try:
            temp = modbusFunction.modbusReadRegister(self, '192.168.1.13', 502, 0x1192, 1)
            print(temp[0])
            QtCore.QMetaObject.invokeMethod(self.supplyTempResualt, "setText",
                QtCore.Qt.QueuedConnection, QtCore.Q_ARG(str, str(temp[0])))
        except Exception as err:
            print(err)
        time.sleep(1)

3. functools.partial with QTimer.singleShot() 3.使用QTimer.singleShot()进行functools.partial

from functools import partial
# ...
def readTemp(self):
    while True:
        try:
            temp = modbusFunction.modbusReadRegister(self, '192.168.1.13', 502, 0x1192, 1)
            print(temp[0])
            QtCore.QTimer.singleShot(0, partial(self.supplyTempResualt.setText, str(temp[0])))
        except Exception as err:
            print(err)
        time.sleep(1)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM