本组的安卓自动化测试软件中,在测试开始前须要进行链接设备的操做,以下图左侧的按钮python
后端MonkeyRunner
相关操做的程序中提供了connect()
函数来供客户端使用,调用该函数会等待链接,并在链接最多5s没有相应以后提示链接失败。可是在客户端未加处理直接调用的时候,整个客户端都会卡死来等待函数的进行,这样会形成不好的用户体验,所以试图采用多线程的方式来解决。后端
最初的解决方案是采用python的threading库来实现多线程,编写了如下代码:安全
def thread_waitingfor_connect(self): while(self.successfully_connect == None ): self.successfully_connect = functions_class.connect() #成功链接之后返回一个设备分辨率的元组(x,y) if(isinstance(self.successfully_connect,tuple)): self.max_x = self.successfully_connect[0] self.max_y = self.successfully_connect[1] self.InputAssignmentButton.setEnabled(True) self.connectDeviceButton.setEnabled(False) self.loadButton.setEnabled(True) self.connectDeviceButton.setText('已成功链接') break #self.connectDeviceButton.setText("从新链接") elif(self.successfully_connect == False): self.connectDeviceButton.setEnabled(True) self.successfully_connect = None self.connectDeviceButton.setText('从新链接') break
而后链接按钮的点击信号所绑定的槽函数里加入线程启动的代码:多线程
self.connect_thread = threading.Thread(target = self.thread_waitingfor_connect) self.connect_thread.start()
就这样能够初步实现如下效果:点击链接之后按钮变成不可用,按钮文本变为“链接中...” 直到链接完成函数
可是这样的实现效果是有局限性的,UI部分代码放在线程中执行彷佛不安全。并且后端提供的connect()
函数在某些状况下返回时间会过长,当我想要在链接时间太久时经过QMessageBox来提示信息的时候,程序就会卡死。在Qt的编码规范中,子线程通常只用于信号的传递,不在子线程代码中直接更改UI,有助于避免程序崩溃。Qt提供了Qthread线程库来实现经过子线程来传递信号的功能。测试
用Qthread重写后的链接代码:编码
class WaitConnect(QtCore.QThread): def __init__(self, t, parent=None): super(WaitConnect, self).__init__(parent) self.t = t self.finished.connect(t.after_connect)#线程执行完成后发射finished信号,执行t.after_connect槽函数 def run(self): self.t.successfully_connect = functions_class.connect() #in class TWindow #把功能代码放入单独的函数中等待完成信号 def after_connect(self): if (isinstance(self.successfully_connect, tuple)): self.max_x = int(self.successfully_connect[0]) self.max_y = int(self.successfully_connect[1]) # self.rate_tuple = self.su self.InputAssignmentButton.setEnabled(True) self.connectDeviceButton.setEnabled(False) self.loadButton.setEnabled(True) self.connectDeviceButton.setText('已成功链接') # self.connectDeviceButton.setText("从新链接") elif (self.successfully_connect == False): self.connectDeviceButton.setEnabled(True) # self.successfully_connect = None self.connectDeviceButton.setText('从新链接')
用QThread实现等待时间超过10s之后出现提示框:线程
class TimeWaitThread(QtCore.QThread): def __init__(self,t,parent = None): super(TimeWaitThread,self).__init__(parent) self.finished.connect(t.wait_about)#完成后执行wait_about函数 def run(self): self.sleep(10) #in class TWindow def wait_about(self): if(self.successfully_connect == None): QMessageBox.about(self,'提示','链接时间过长,请检查您的环境配置和链接状态') self.connectDeviceButton.setEnabled(True) self.successfully_connect = None self.connectDeviceButton.setText('从新链接')
注意:QThread和threading在使用中不一样的一点在于,threading的线程start之后是不会被python的gc回收的,而QThread线程若是做为局部变量,会在函数执行结束之后就被gc,致使线程莫名其妙终结,所以线程变量推荐做为类的成员变量或者全局变量存在。code