首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

PyQt5:开局只有5个农民,从荒岛到建立帝国!1

PyQt5

54篇

PyQt5:开局只有5个农民,从荒岛到建立帝国!(QTimer与QThread的综合应用举例)1

导读:Warcraft III

LEARN MORE

正文

前几期我们学习了QMdiArea类,在一个窗口实现了多个窗口部件的呈现,今天我们再来一个综合性的例子,讲解一下QTimer与QThread的综合使用。

1

总体介绍

QTimer类

还记得我们在

《PyQt5:液晶显示屏》

倒计时的例子吗?在那个例子中我们使用了QTimer类实现了定时触发槽函数的功能。

QTimer类提供重复和单次定时器。

QTimer类为定时器提供高级编程接口。要使用它,请创建一个QTimer,将其timeout()信号连接到相应的插槽,然后调用start()。从那时起,它将以恒定的间隔发出timeout()信号。

一秒(1000毫秒)定时器的示例(来自模拟时钟示例):

从那时起,每隔一秒调用update()这个槽函数。

您可以通过调用setSingleShot(True)将计时器设置为仅超时一次。您还可以使用静态QTimer.singleShot()函数在指定的时间间隔后调用槽函数:

精度

定时器的准确性取决于底层操作系统和硬件。大多数平台支持1毫秒的分辨率,但在许多实际情况下,定时器的精度将不等于此分辨率。

精度还取决于计时器类型。对于Qt.PreciseTimer,QTimer将尝试将精度保持在1毫秒。精确的计时器也永远不会超出预期的时间。

对于Qt.CoarseTimer和Qt.VeryCoarseTimer类型,QTimer可能会在这些类型的边距内提前唤醒:Qt.CoarseTimer的间隔为5%,Qt.VeryCoarseTimer为500 ms。

如果系统繁忙或无法提供所要求的准确度,则所有计时器类型可能会超出预期的时间。在超时超限的情况下,Qt将仅发出一次activate(),即使多个超时已到期,然后将恢复原始时间间隔。

QTimer的替代品

使用QTimer的另一种方法是为对象调用QObject.startTimer()并重新实现类中的QObject. timerEvent()事件处理程序(必须继承QObject)。缺点是timerEvent()不支持单次定时器或信号等高级功能。

另一种选择是QBasicTimer。它通常不如直接使用QObject.startTimer()那么麻烦。有关所有三种方法的概述,请参见计时器。

更多内容请参见:https://doc.qt.io/qt-5/qtimer.html

QThread类

QThread类提供了一种独立于平台的管理线程的方法。

QThread对象管理程序中的一个控制线程。 QThreads开始在run()中执行。默认情况下,run()通过调用exec()启动事件循环并在线程内运行Qt事件循环。

您可以使用QObject.moveToThread()将worker对象移动到线程来使用它们(此种方式这里不做介绍)。

使代码在单独的线程中运行的另一种方法是继承QThread并重新实现run()。例如:

在该示例中,线程将在运行函数返回后退出。除非你调用exec(),否则线程中不会运行任何事件循环。

重要的是要记住,QThread实例存在于实例化它的旧线程中,而不是在调用run()的新线程中。这意味着所有QThread的排列函数和调用的方法都将在旧线程中执行。因此,希望在新线程中调用槽函数的开发人员必须使用worker-object方法。

直接在QThread对象上调用的方法将在调用该方法的线程中执行。在继承QThread时,请记住构造函数在旧线程中执行,而run()在新线程中执行。如果从两个函数访问成员变量,则从两个不同的线程访问该变量。

注意:在跨不同线程的对象交互时必须小心。

管理线程

当线程started()和finished()时,QThread将通过信号通知您,或者您可以使用isFinished()和isRunning()来查询线程的状态。

您可以通过调用exit()或quit()来停止该线程。在极端情况下,您可能希望强制terminate()正在执行的线程。但是,这样做是危险和沮丧的。

使用wait()来阻塞调用线程,直到另一个线程完成执行(或直到指定的时间过去)。

QThread还提供静态的,独立于平台的睡眠功能:sleep(),msleep()和usleep()分别允许秒,毫秒和微秒的睡眠级别。

注意:一般来说,wait()和sleep()函数是不必要的,因为Qt是一个事件驱动的框架。考虑监听finished()信号,而不是wait()。请考虑使用QTimer,而不是sleep()函数。

更多内容请参见:https://doc.qt.io/qt-5/qthread.html

类归属

PyQt5->QtCore->QTimer

PyQt5->QtCore->QThread

继承关系

PyQt5->QObject->QTimer

PyQt5->QObject->QThread

2

小例子

本期我模拟了魔兽世界游戏中人族挖金矿这个环节。我们设定了挖矿的时间10-1000秒之间,最后给你一个你挖到金矿的结果。

主要是通过QTimer动态的加载进度条,告知我们现在的挖矿进度。挖矿这个过程不在主线程(否则就是未响应),参考这里:《PyQt5番外篇(2-5):冲顶大会语音答题辅助小工具之解析篇——问题搜索及程序整合》。

挖矿我们怎么模拟的呢?我们知道ASCII码可以表示256种可能的字符,我们选取一种作为金矿。同时我们知道金矿在自然界中是非常稀有的,我们在随机选择ASCII字符的时候,降低作为金矿的ASCII码字符被选中的概率,让其更加珍惜。

具体的代码说明在下期吧!代码我还想再斟酌一下!

3

最后

好的,今天这期就这样结束吧。如果你喜欢本篇文章,请给我点赞

赞赏(推荐)

分享给你的好友们吧!

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180706G1F2OT00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券