PyQt即时刷新

即时刷新

问题简介

  • 近来在项目中遇到一个问题,用PYQT5实现KNN算法的手写文字识别练习项目,在做训练集过程中,调用信号与槽,将训练执行状态在界面的QLable中显示,但是信号也发送了,槽函数也调用了,槽函数中的打印语句也执行了,就是QLable死活更改不成功,窗体的SetWindowText也可以实现。
PyQt即时刷新_第1张图片
程序假死.png

解决办法

  • 有时候需要处理一些跟界面无关的但非常耗时的事情,这些事情跟界面在同一个线程中,由于时间太长,导致界面无法响应,处于“假死”状态。例如:在应用程序中保存文件到硬盘上,从开始保存直到文件保存完毕,程序不响应用户的任何操作,窗口也不会重新绘制,从而处于“无法响应”状态,这是一个非常糟糕的体验 。

    • 在这种情况下,有一种方法是使用多线程,即在子线程中处理文件保存,主线程负责界面相关。

    • 而如果不想使用多线程,最简单的办法就是在文件保存过程中频繁调用QApplication.processEvents()。该函数的作用是让程序处理那些还没有处理的事件,然后再把使用权返回给调用者。

  • 先写一个简单的demo

   import sys
   from PyQt5.QtCore import pyqtSignal, QObject
   from PyQt5.Qt import QIcon
   from PyQt5.QtWidgets import QMainWindow, QApplication, QLabel
   import time


   class Communicate(QObject):

       closeApp = pyqtSignal()


   class Example(QMainWindow):

       def __init__(self):
           super().__init__()

           self.initUI()


       def initUI(self):

           self.c = Communicate()
           self.c.closeApp.connect(self.showMsg)

           self.setGeometry(300, 300, 290, 150)
           self.setWindowTitle('Emit signal')
           self.lable = QLabel("hello", self)
           self.show()

       def mousePressEvent(self, event):

           self.c.closeApp.emit()

       def showMsg(self):
           print("ok")
           self.lable.setText("hahah")
           time.sleep(10)
           self.lable.setText("wait")

   if __name__ == '__main__':
       app = QApplication(sys.argv)
       ex = Example()
       sys.exit(app.exec_())
  • 点击尽管可以打印出ok,但是无法将hello改为hahah,在程序假死结束之后则会直接改为wait,或者说执行过但是看不出来
PyQt即时刷新_第2张图片
执行.gif
  • 将QApplication.processEvents()加入槽函数中即可解决这个问题

      def showMsg(self):
          print("ok")
          self.lable.setText("hahah")
          QApplication.processEvents()
          time.sleep(10)
          self.lable.setText("wait")
    
PyQt即时刷新_第3张图片
执行2.gif

你可能感兴趣的:(PyQt即时刷新)