使用PyQt线程的正确姿式前端
用了Python一段时间了,图形编程看了一些,仍是以为PyQt比较方便,主要得益于designer和uic两个工具,使得前端页面可视编程,也方便转换为代码。关于这两个工具的使用网上一大堆,我以为并无必要重复,只有有一点要提醒你们注意,就是用uic生成的程序文件千万别动!!!新写一个类继承它,须要增长的方法都放在子类里面,这样咱们从新修改ui文件,再用uic生成代码的时候就不用再修改太多(若是不修改已有的控件名就不用修改)。编程
说到图形界面,就避开不了线程,毕竟UI主线程必须保证事件循环不被阻塞来响应用户的输入。一开始使用PyQt的时候,程序动不动就未响应,后来才知道是由于把须要长时间运行的代码放在了主线程,阻塞了事件循环。这时候,咱们便须要把这部分代码移到其余线程,经过信号与槽来实现线程间的通讯。所谓线程,按照我目前的理解,是包含了本身的事件循环机制,所谓事件循环,也就是说当线程接收到信号的时候,若是有响应的槽,能够作出响应。同时,线程还能够发送信号给其余线程,信号能够带参数。网络
因为写博客的时间有点仓储,本博客里面的代码所有是截取我最近的项目里面的代码,但跟博客内容有关的部分我会尽可能呈现和说明清楚,望见谅。多线程
QtCore.QThread是一个管理线程的类,当咱们使用其构造函数的时候,便新建了一个线程。这里要强调,QThread是一个线程管理器,不要把业务逻辑放在这个类里面,Qt的做者已经屡次批评继承QThread类来实现业务逻辑的作法。那么,咱们怎样把代码放到Thread中运行呢?答案以下:ide
self.writing_thread = QtCore.QThread()
self.writer.moveToThread(self.writing_thread)
咱们把业务逻辑写在一个QtCore.QObject的子类里面,而后新建一个实例,例如上述代码的writer,而后调用继承了父类的方法moveToThread,这样就能够把该对象放在线程里面。剩下的工做就是经过信号和槽的机制处理业务逻辑和返回结果了。通常来讲,槽函数所在的类在哪一个线程,这个函数就在哪一个线程执行。函数
http://www.javashuo.com/article/p-uctpfrei-ed.html工具
pyqt多线程moveToThread的使用ui
建立一个QObject子类 该类包含要在子线程中运行的代码,以及在子线程运行过程当中须要发回主线程的信号。如下为例: class AnalyzObject(QObject): def __init__(self,parent=None): super(AnalyzObject,self).__init__(parent) #开始调用网络的信号 stop_analyz_signal=pyqtSignal() start_print_result=pyqtSignal() def analyz_work(self): test_video() self.start_print_result.emit() self.stop_analyz_signal.emit() 其中,analyz_work是要子线程中所要运行的代码。 实例化QObject子类,并转移到子线程中。 回到主线程,先将AnalyzObject(本例中)实例化,再新建立一个子线程,将实例化的AnalyzObject转移到子线程中,如下为代码: self.analyz_thread=QThread() self.analyze=AnalyzObject() self.analyze.moveToThread(self.analyz_thread) 开始线程 在但愿激活子线程的时候加入代码: self.analyz_thread.started.connect(self.analyze.analyz_work) self.analyz_thread.start() 结束线程 self.analyze.stop_analyz_signal.connect(self.stop_analyze) def stop_analyze(self): self.analyz_thread.quit()