pyqt 主程序运行中处理其他事件(多线程的一种代替方式)
一、实验环境
1.Windows7x64_SP1
2.Anaconda2.5.0 + python2.7(anaconda集成,不需单独安装)
3.pyinstaller3.0
4.通过Anaconda Navigator安装pyqt5
二、背景如下
2.1 程序要求
单击“Ping_Test”按钮后,按钮文本变换为“Waitting...”,同时TextEdit控件中显示“ping测试中,请等待...”,ping动作完成后,TextEdit控件中显示ping的结果。
2.2 代码实现
代码全部放在ping函数中,函数代码不再给出
self.ui.ping_test.clicked.connect(self.ping)
2.3 产生问题
运行程序发现,未能实现2.1的预期要求,按下按钮,ping动作完成后,“Ping_Test”按钮才显示“Waitting...”;另外“TextEdit”控件未显示“ping测试中,请等待...”,直接显示ping的结果
2.4 原因分析
按钮按下之后,未执行窗口重绘,准确来说未处理控件文本改变事件,ping动作之后一并处理。
三、实现步骤
3.1 实现方式一
鼠标单击动作分为两种,pressed和clicked,前者为鼠标左键按下,后者为鼠标左键按下并释放。代码实现如下:
self.ui.ping_test.pressed.connect(self.ping_change_text) self.ui.ping_test.clicked.connect(self.ping)
def ping_change_text(self): self.ui.ping_test.setText('Waitting...') self.ui.textEdit.setText('ping测试中,请等待...') def ping(self): self.ui.ping_test.setEnabled(False) self.debug_print('ping test') smartbit_ip = self.ui.ip_list.currentText() if smartbit_ip: QApplication.processEvents() ret_ping = os.popen('ping %s -w 3' %(smartbit_ip)).read() if '100%' in ret_ping: self.ui.get_user.setEnabled(False) self.ui.textEdit.setText('ping测试失败,请确认网络连接或者仪器是否正常') else: self.ui.get_user.setEnabled(True) self.ui.textEdit.setText('ping测试成功,请按下Get_User按钮') else: self.ui.textEdit.setText('SmartBit IP地址为空!') self.ui.ping_test.setEnabled(True) self.ui.ping_test.setText('Ping_Test')
3.2 实现方式二,推荐该方式
使用QApplication.processEvents函数,使该函数调用前面事件优先执行。代码如下
from PyQt5.QtWidgets import QApplication,QDialog self.ui.ping_test.clicked.connect(self.ping)
def ping(self): self.ui.ping_test.setText('Waitting...') self.ui.textEdit.setText('ping测试中,请等待...') self.ui.ping_test.setEnabled(False) self.debug_print('ping test') QApplication.processEvents() smartbit_ip = self.ui.ip_list.currentText() if smartbit_ip: QApplication.processEvents() ret_ping = os.popen('ping %s -w 3' %(smartbit_ip)).read() if '100%' in ret_ping: self.ui.get_user.setEnabled(False) self.ui.textEdit.setText('ping测试失败,请确认网络连接或者仪器是否正常') else: self.ui.get_user.setEnabled(True) self.ui.textEdit.setText('ping测试成功,请按下Get_User按钮') else: self.ui.textEdit.setText('SmartBit IP地址为空!') self.ui.ping_test.setEnabled(True) self.ui.ping_test.setText('Ping_Test')