PYQT中使用线程解决界面卡顿问题


  PYQT作为界面程序包,为Pythoner快速构建界面,提供了便利性。特别是结合Pycharm扩展工具(QTdesigner)能够通过“拖拖拽拽”的方式构建简单界面。通过UIC将UI文件快速转化为PY文件,节省了时间。

  PYQT的项目实践,必须参照MVC模式,才能形成多人工作合力,关于MVC的实践,会另起它文进行总结归纳,本文重点总结归纳PYQT项目中,因耗时操作产生界面卡顿现象时,如何通过分线程的方式,解决主界面线程等待造成界面卡顿的问题。

  一、问题的出现

  设计了一个界面,去局域网共享文件夹中查看是否存在文件,若存在,则在textBrowser中显示文件数量,每隔几秒钟执行一次,同时将信息Append到textBrowser中。

  使用os.listdir(target_path)打开共享文件夹时,由于网络故障,待反馈耗时大,由于Ui_MainWindow中的方法都在主线程中进行,造成界面的卡顿。

  二、解决思路

  将耗时操作分离至新线程,主界面保留资源用于交互。查询网络上现有的解决思路,大致如下:利用PYQT中的QThread类,新起一个线程,用来处理共享文件夹查阅的操作,待该线程处理完成后,主线程接收子线程处理结果,append到textBrowser中。

  三、难点

  利用信号与槽的机制,将主、子线程建立关联关系。

  四、如何实现

  1、实例化Ui_MainWindow类的MyThread对象,用于填装子线程处理任务。

  self.my_thread = MyThread()

  2、将事件信号与槽函数建立联系,通过count函数启用线程。

  self.StopButton.clicked.connect(self.CountFilesNum)

  3、Count函数:

  self.textBrowser_2.append("开始检测……")
  self.my_thread.is_on = True
  self.my_thread.start()#启动线程

  4、设计MyThread类,继承Qthread类

  my_signal = pyqtSignal(str)  #

  tipwords = ''
  def __init__(self):
      super(MyThread, self).__init__()
      self.tipwords = ''
      self.is_on = True

  定义一个信号(my_signal)用于向槽函数传递字符型变量(字符会输出到textBrowser中),调用父类的INIT方法,完成初始化设置。

  5、定义线程中的主逻辑函数:

  all_content = os.listdir(target_path)

  ……

  self.my_signal.emit(str(self.tipwords))  

  函数执行完,释放信号。线程中的信号关联到append函数

  self.my_thread.my_signal.connect(self.appendTextBrowser)  

  实现了线程中数据返回主线程的目的。

  五、总结

  除了button中的信号与槽机制外,主、子线程也是通过信号与槽机制完成的关联,可见,信号与槽机制,确实是PYQT的核心。

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM