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的核心。