【问题标题】:PyQt5 GUI only updates when screen is clicked off and back onPyQt5 GUI 仅在单击屏幕并重新打开时更新
【发布时间】:2016-11-02 07:47:38
【问题描述】:

当我通过串行获取值然后尝试使用这些值更新我的 Gui 时遇到了问题。不幸的是,即使值正确更新,我也无法进入屏幕刷新,除非我单击它然后重新打开它。我已经尝试过重绘、更新和 processEvents(),但都无法解决问题。

这是我正在使用的代码:

import sys
import serial
import time
import requests


import PyQt5
from PyQt5.QtWidgets import *
from PyQt5.QtCore import*
from PyQt5.QtGui import *

import mainwindow_auto


CUSTOM_EVENT = 1000
ser = serial.Serial('/dev/ttyACM0', 9600)
class TestThread(QThread):

    def __init__(self, target):
        QThread.__init__(self)
        self.target = target

    def run(self):
        while True:
            QApplication.postEvent(self.target, QEvent(QEvent.Type(CUSTOM_EVENT)))
            QApplication.processEvents()
            QThread.sleep(15)




class MainWindow(QMainWindow, mainwindow_auto.Ui_MainWindow):

    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)# gets defined in the UI file
        self.thread = TestThread(self)
        self.thread.start()

    def event(s, e):
        if(e.type() == CUSTOM_EVENT):
            print("Readline: ",int(ser.readline()))
            SOC = int(ser.readline())
            s.lcdNumber.display(SOC)
            s.progressBar.setValue(SOC)
            print("SOC: ",SOC)
            print(s.lcdNumber.value())

        return True


def main():

    app = QApplication(sys.argv)
    form = MainWindow()
    form.lcdNumber.display(30)
    form.progressBar.setValue(30)
    form.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

提前致谢!

【问题讨论】:

    标签: python qt user-interface pyqt pyqt5


    【解决方案1】:

    既然你已经有了一个 I/O 线程,让它处理 I/O 并将接收到的值通过信号发送到主线程。

    不需要自定义事件,主线程上没有 I/O。 只需在线程子类中添加一个信号并在启动线程之前将一个插槽连接到该子类。

    【讨论】:

    • 嗨凯文!谢谢你快速的回复!我尝试按照您建议的路线进行,但最终进行了大量调试(第一次使用 PyQt)。我最终通过隐藏和重新显示屏幕来强制重绘来解决它。可能不是最佳实践,但到目前为止它一直很稳定。再次感谢您的帮助!
    【解决方案2】:

    我没有重写上面的代码,而是在更新事件代码中的值后通过使用 s.hide() 和 s.show() 强制重绘来修复它。它强制重新绘制,否则将无法正常工作。

    s.lcdNumber.display(SOC)
    s.progressBar.setValue(SOC)
    s.hide()
    s.show()
    

    【讨论】:

      【解决方案3】:

      正如@KevinKrammer 所建议的,使用自定义信号很简单:

      class TestThread(QThread):
          serialUpdate = pyqtSignal(int)
      
          def run(self):
              while True:
                  QThread.sleep(1)
                  value = int(ser.readline())
                  self.serialUpdate.emit(value)
      
      class MainWindow(QMainWindow, mainwindow_auto.Ui_MainWindow):
          def __init__(self):
              super(MainWindow, self).__init__()
              self.setupUi(self)
              self.thread = TestThread(self)
              self.thread.serialUpdate.connect(self.handleSerialUpdate)
              self.thread.start()
      
          def handleSerialUpdate(self, value):
              print("Readline: ", value)
              self.lcdNumber.display(value)
              self.progressBar.setValue(value)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-04-12
        • 2013-05-16
        • 1970-01-01
        • 1970-01-01
        • 2014-02-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多