当前位置:   article > 正文

《快速掌握PyQt5》第十章 定时器QTimer和进度条QProgressBar_pyqt5 qtimer(self, timeout=self.update)

pyqt5 qtimer(self, timeout=self.update)

第十章 定时器QTimer和进度条QProgressBar

10.1 QTimer

10.2 QProgressBar

10.3 小结


《快速掌握PyQt5》专栏已整理成书出版,书名为《PyQt编程快速上手》,详情请见该链接。感谢大家一直以来的支持!祝大家PyQt用得越来越顺!

当我们要让程序定期去执行某函数的时候,QTimer就派上用场了,比如一个游戏程序,它通常会定期去调用一个函数来进行更新操作。而进度条可以用来显示某项任务的进度,从而让用户界面更加友好。

我们通常将将QTimer和QProgressBar一起搭配使用,所以本章就一起介绍了。

10.1 QTimer

以下这个程序中,按钮被点击后,QLabel显示的数字会不断增加:

  1. import sys
  2. from PyQt5.QtCore import QTimer, Qt
  3. from PyQt5.QtWidgets import QApplication, QWidget, QPushButton, QLabel, QVBoxLayout
  4. class Demo(QWidget):
  5. def __init__(self):
  6. super(Demo, self).__init__()
  7. self.label = QLabel('0', self) # 1
  8. self.label.setAlignment(Qt.AlignCenter)
  9. self.step = 0 # 2
  10. self.timer = QTimer(self) # 3
  11. self.timer.timeout.connect(self.update_func)
  12. self.ss_button = QPushButton('Start', self) # 4
  13. self.ss_button.clicked.connect(self.start_stop_func)
  14. self.v_layout = QVBoxLayout()
  15. self.v_layout.addWidget(self.label)
  16. self.v_layout.addWidget(self.ss_button)
  17. self.setLayout(self.v_layout)
  18. def start_stop_func(self):
  19. if not self.timer.isActive():
  20. self.ss_button.setText('Stop')
  21. self.timer.start(100)
  22. else:
  23. self.ss_button.setText('Start')
  24. self.timer.stop()
  25. def update_func(self):
  26. self.step += 1
  27. self.label.setText(str(self.step))
  28. if __name__ == '__main__':
  29. app = QApplication(sys.argv)
  30. demo = Demo()
  31. demo.show()
  32. sys.exit(app.exec_())

1.  首先实例化一个QLabel,并将文本设为0。setAlignment(Qt.AlignCenter)可以让QLabel控件在窗口中居中显示,而之前我们是通过addStretch(int)方法来让一个控件在布局中居中的,显然通过setAlignment(Qt.AlignCenter)方法更加方便:

  1. self.h_layout.addStretch(1)
  2. self.h_layout.addWidget(self.label)
  3. self.h_layout.addStretch(1)

2. step变量用于计数,QLabel控件显示的就是这里的step,程序会通过QTimer来不断增加step的值;

3. 其次实例化一个QTimer,并将timeout信号连接到自定义的槽函数update_func()上: 

  1. def update_func(self):
  2. self.step += 1
  3. self.label.setText(str(self.step))

每次调用该槽函数就会将step值加1,并且用QLabel显示当前值;

4. 最后我们实例化一个QPushButton按钮来控制定时器的启动的停止,连接的自定义的槽函数如下:

  1. def start_stop_func(self):
  2. if not self.timer.isActive():
  3. self.ss_button.setText('Stop')
  4. self.timer.start(100)
  5. else:
  6. self.ss_button.setText('Start')
  7. self.timer.stop()

在槽函数中通过isActive()方法来判断定时器是否处于激活状态,若没有激活,则将按钮文字变成Stop并通过start(100)方法来启动定时器,100表示100毫秒,也就是说每过0.1秒,定时器就会触发timeout信号,并执行update_func()槽函数;若已经处于激活状态,则将按钮文字变回Start并通过stop()方法停止定时器。

有些小伙伴可能想在触发timeout信号后只调用一次update_func(),那么我们可以通过setSingleShot(True)方法来设置。

运行截图如下:

10.2 QProgressBar

这里我们将10.1章节中的QLabel用QProgressBar来代替:

  1. import sys
  2. from PyQt5.QtCore import Qt, QTimer
  3. from PyQt5.QtWidgets import QApplication, QWidget, QProgressBar, QPushButton, QHBoxLayout, QVBoxLayout
  4. class Demo(QWidget):
  5. def __init__(self):
  6. super(Demo, self).__init__()
  7. self.progressbar = QProgressBar(self) # 1
  8. # self.progressbar.setOrientation(Qt.Vertical)
  9. self.progressbar.setMinimum(0) # 2
  10. self.progressbar.setMaximum(100)
  11. # self.progressbar.setRange(0, 100)
  12. self.step = 0 # 3
  13. self.timer = QTimer(self) # 4
  14. self.timer.timeout.connect(self.update_func)
  15. self.ss_button = QPushButton('Start', self) # 5
  16. self.ss_button.clicked.connect(self.start_stop_func)
  17. self.reset_button = QPushButton('Reset', self) # 6
  18. self.reset_button.clicked.connect(self.reset_func)
  19. self.h_layout = QHBoxLayout()
  20. self.v_layout = QVBoxLayout()
  21. self.h_layout.addWidget(self.ss_button)
  22. self.h_layout.addWidget(self.reset_button)
  23. self.v_layout.addWidget(self.progressbar)
  24. self.v_layout.addLayout(self.h_layout)
  25. self.setLayout(self.v_layout)
  26. def start_stop_func(self):
  27. if self.ss_button.text() == 'Start':
  28. self.ss_button.setText('Stop')
  29. self.timer.start(100)
  30. else:
  31. self.ss_button.setText('Start')
  32. self.timer.stop()
  33. def update_func(self):
  34. self.step += 1
  35. self.progressbar.setValue(self.step)
  36. if self.step >= 100:
  37. self.ss_button.setText('Start')
  38. self.timer.stop()
  39. self.step = 0
  40. def reset_func(self):
  41. self.progressbar.reset()
  42. self.ss_button.setText('Start')
  43. self.timer.stop()
  44. self.step = 0
  45. if __name__ == '__main__':
  46. app = QApplication(sys.argv)
  47. demo = Demo()
  48. demo.show()
  49. sys.exit(app.exec_())

1. 实例化一个QProgressBar,默认是水平的,但是我们可以通过setOrientation(Qt.Vertical)方法来让进度条垂直显示;

2. 通过setMinimum()和setMaximum()方法来设置范围,也可以单单用setRange()方法来实现,这里我们将范围设为0-100;

3. 这里的step变量用于计数,之后QProgressBar会将值设为step;

4. 实例化一个QTimer,并将timeout信号连接到update_func()槽函数上:

  1. def update_func(self):
  2. self.step += 1
  3. self.progressbar.setValue(self.step)
  4. if self.step >= 100:
  5. self.ss_button.setText('Start')
  6. self.timer.stop()
  7. self.step = 0

每次触发timeout都会调用该槽函数,在这里我们将step值加1,并将progressbar的值设为step,当step值达到pregress的最大值时(也就是说进度条达到100%),将按钮文本重新设为Start,停止定时器并将step值重设为0;

5. 实例化一个QPushButton按钮来控制QTimer的启动与停止,这里将它的clicked信号和start_stop_func()槽函数连接起来:

  1. def start_stop_func(self):
  2. if self.ss_button.text() == 'Start':
  3. self.ss_button.setText('Stop')
  4. self.timer.start(100)
  5. else:
  6. self.ss_button.setText('Start')
  7. self.timer.stop()

在槽函数中,我们通过按钮文字来进行判断,若为Start,则说明定时器没有启动,所以将按钮文字设为Stop,并且通过start(100)方法来启动,100表示100毫秒,即0.1秒。也就是说之后每隔0.1秒就会触发timeout信号并调用update_func()槽函数;若按钮文字为Stop,则将其设为Start并停止定时器(我们在10.1章节中时通过定时器isActive()方法来的,当然这里也可以使用);

6. 该实例化的按钮用于重置进度条:

  1. def reset_func(self):
  2. self.progressbar.reset()
  3. self.ss_button.setText('Start')
  4. self.timer.stop()
  5. self.step = 0

其所连接的槽函数中通过reset()方法来进行重置,还有将按钮文字设为Start,停止定时器以及将step值设为0。

运行截图如下:

10.3 小结

1. QTimer定时器会根据设定的时间不断发出timeout信号并调用连接的槽函数,通过start(int)方法来设置时间并启动定时器,stop()方法用于停止定时器;

2. 通过isActive()方法来判断定时器是否被激活,setSingleShot()方法可以在触发timeout信号后只调用一次槽函数;

3. 通过setOrientation(Qt.Vertical)方法可以将进度条设为垂直显示;

4. setMinimum()和setMaximum()方法用来设置进度条范围(可以用setRange()替代),setValue()方法用于设置进度条的当前值,reset()方法用于重置进度条。

bug记录:在Mac上QPushButton的文字改变有点问题。

欢迎关注我的微信公众号,发现更多有趣内容:

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/264426?site
推荐阅读
相关标签
  

闽ICP备14008679号