本篇将会涉及:
- 保持GUI程序响应
- sleep()冻结整个GUI程序
- 开始、停止和重置我们的导航条
- 使用多线程和pyqt信号
改善按钮对进度栏的控制
上一篇中我们创建了一个稍显复杂的GUI,并且编写了一些逻辑方法来控制一些按钮和部件的行为。其中,我们设置了三个按钮,用来控制进度条,但是功能还不是很完善。
我们现在将其改进一下:
- 第一个按钮用来启动进度栏;
- 第二个按钮用来停止进度栏;
- 第三个按钮用来重置进度栏;
在之前的MainWindow类中,我们对进度条和按钮的事件设置三个方法:
我们将上述三个方法修改一下,改写成四个方法:
- start_progressbar(self):用于启动进度栏
- stop_progressbar(self):用于停止进度栏
- reset_progressbar(self):用于重置进度栏
- update_progressbar(self):用于绑定三个按钮到上述三个方法上
运行程序,看看效果:
当我们点击“开始”按钮,进度栏便开始增加,当我们点击“停止按钮”,进度栏便停止增加,当我们点击“重置”按钮,进度栏便归零。
控制进度栏增长速度
在启动进度栏的start_progressbar()方法中,我们通过while循环来增加进度栏,每次增加0.0001,在这样的情况下,进度栏增长得很快。其实,我们可以通过time模块的sleep()方法冻结进度栏,以达到降低进度栏增长速度的效果。
修改start_progressbar()方法如下:
我们让进度栏的数值增长停歇0.3秒,看看效果:
进度栏的增长速度确实比之前缓慢了很多。
使用QThread线程
PyQt中QtCore的QThread对象提供了一个独立于平台的方式来管理线程。
QThread对象通过调用run()方法来执行线程,默认情况下,run()方法通过调用exec()方法来启动事件的循环。
下面,我们通过一个进度栏计数器的示例,来演示一下QThread的使用。
我们新建一个继承自QtCore.QThread的类RunThread(),并在其中定义一个run()方法用来启动线程,定义一个stop()方法用来停止线程。
首先,我们通过实例化QtCore.pyqtSignal(int)定义了一个新的信号counter_value,这个值会用来更新进度栏。然后设置了RunThread()类中的一些默认属性。
在run()方法中,我们通过一个while循环来不断累加计数器的值,并且将累加的计数器的值通过定义的信号counter_value发送出去。
在stop()方法中,我们设置线程的运行状态为Fasle,然后使用QThread的terminate()方法确保线程完全的被停止。
然后,要应用这个进度栏计数器,我们还需要在主窗口类MainWindow()中添加和修改一番:
添加一个进度栏计数器方法progressbar_counter(),用来启动线程管理器:
添加一个进度栏设置方法set_progressbar(),用来设置进度栏的值:
修改一下进度栏的启动方法start_progressbar()。删除while循环,添加进度栏计数器到其中(因为进度栏计数器中已经实现了while循环增加数值):
修改进度栏的停止方法stop_progressbar(),添加线程的stop()方法用来停止线程:
修改完成后,我们运行程序,看看效果:
通过终端打印出来的信息,我们可以直观的看到QThread线程的管理控制。
本篇到此告一段落,如果文中有错误欢迎指正,如果有疑问欢迎留言讨论。
感谢阅读!
文章版权所有:州的先生博客,转载必须保留出处及原文链接
教程最后关于线程控制部分,漏了对 reset_progressbar() 函数修改的描述,
要在该函数内加入self.stop_progressbar(),不然重置钮没用
教程最后漏了对 reset_progressbar() 函数的修改,要在该函数内加入self.stop_progressbar(),不然重置钮没用
多谢指正:)
如何实现多个线程,比如程序如,有两个或三个循环需要控制
使用Qthread进行对UI界面和功能函数进行分离
三个方法改为四个后为什么没结果
按钮要绑定连接到具体的方法上才有效果
建议 开启线程之前先关掉可能有的副线程,这样按了多次开始按钮就不会有多个progress线程在跑了 主要是reset的时候会出现问题
def progrossbar_counter(self,start_value=0):
try:
self.run_thread.stop()
except:
pass
嘤嘤嘤,大学在校萌新想看整个源代码【我才不说是我分不清哪个是哪个】
进度条不会变化,求救