PyQt - 使用多线程避免界面卡顿

本文探讨了PyQt界面程序中遇到的界面卡顿问题及其解决办法。通过使用多线程技术,特别是QThread,可以有效避免长时间操作导致的界面无响应。介绍了两种常见多线程实现方式及信号与槽机制的应用。

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的核心。
      在使用pyqt开发界面时,遇到了一种情况,就是在点击按钮之后,响应函数中会启动一个循环,该循环会一直执行,然后就造成界面无响应,如下所示,由于我是在Linux下运行的,所以界面直接显示成灰色(windows应该显示“无响应”):

这是因为对于pyqt来说,界面线程是主线程,如果我们在主线程函数里面调用了一个耗时比较久的循环,可能就会造成主界面线程卡死在循环中,从而造成无法操作主界面或者主界面卡顿、卡死。

所以这种情况下必须使用多线程的方式来解决,即在主界面线程中在启动一个新的子线程,利用该子线程处理比较耗时的操作,然后通过signal-slot机制将子线程的数据反馈到主界面线

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值