Pyqt5如何停止多线程

 我来答
约定20125
2018-05-28 · TA获得超过1.5万个赞
知道大有可为答主
回答量:1.1万
采纳率:96%
帮助的人:2932万
展开全部

以下用一个简单例子来表现如何用signal/slot信号槽来退出线程。

若有一个按钮,点击开始线程,再次点击退出线程,线程的工作为打印a(1-20)然后b(1-20),线程代码如下:

[python] view plain copy

  • class UpdateThread(QThread):  

  • def __init__(self, parent=None):  

  • super(UpdateThread, self).__init__(parent)  

  • self.flag = 1# 用来判断循环是否继续的标志,通过改变该标志来使得线程中run函数退出  

  • def run(self):  

  • table = ['a', 'b', 'c', 'd ', 'e', 'f', 'g']  

  • for i in range(6):  

  • if self.flag == 1:  

  • print table[i]  

  • for m in range(20):  

  • print m  

  • time.sleep(0.5)  

  • else:  

  • break  

  • print 'close'# 输出标明线程run函数已经退出  

  • def stop(self):  

  • print 'setting flag false'  

  • self.flag = 0  

  • print self.flag  

  • 一开始因为python的threading没有线程退出的api,了解到QThread有实现线程的阻塞,退出,强制退出等api,于是就将线程继承了QThread,但是在gui界面的按钮逻辑中写上mythread.wait()或者是quit()还是terminate()都无法对线程产生影响(可能是当时没有使用信号槽机制,所以不起作用),然后自己来写一个stop函数用来修改线程中的一个标志,使得run函数中的循环停止,然后就如上代码所示,在按钮逻辑中如下所写(错误示范):
  • [python] view plain copy

  • def update_db():# error  

  • self.new_thread1 = UpdateDbThread()  

  • if self.update_tag == 0:  

  • self.update_tag = 1  

  • self.new_thread1.start()  

  • else:  

  • self.update_tag = 0  

  • self.new_thread1.stop()  

  • 运行之后发现stop函数虽然改变了self.flag的值,但是循环中判断语句中flag的值依然为1,循环并没有停止,然后就去查阅资料,以及上stackoverflow寻找答案,最终知道了线程需要通过信号槽机制来响应,所以便去查阅qt的signal/slot的相关信息,修改按钮代码如下:

    [python] view plain copy

  • class mywidget(Qwidget):   

  • sin = pyqtSignal()# 提前申明  

  • def __init__(self):  

  • ...  

  • self.new_thread1 = UpdateDbThread()  

  • self.sin.connect(self.new_thread1.stop)  

  • def update_db():  

  • if self.update_tag == 0:   

  • self.update_tag = 1  

  • self.new_thread1.start()   

  • else:   

  • self.update_tag = 0   

  • self.sin.emit()  



  • [python] view plain copy

  • </pre><p></p><pre>  

  • pyqtSignal信号的定义不可以写在update_db方法中,也不可以写在init()初始化方法中,原因如下(来自stackoverflow):


    所以我们就在init方法之前定义好信号sin,然后连接上线程的stop方法。点击按钮发送信号,就好改变线程的标志,然后从循环中退出,运行结果如下:

    为了便于贴图,我将循环输出改为了10:

    线程正常退出,目标达成。可以根据自己的需要重写run方法。

    还有需要注意的是,不可以在方法中写上 mythread = update_db() ,这样在运行时会报错,destroyed while thread is running,因为在方法中mythread是一个局部变量,当方法结束时,python的垃圾回收机制就会自动销毁,然后就会出现以上错误,所以必须在mythread的前面加上self,使得线程成为全局变量

推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式