- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个 GUI 女巫,我需要使用 Qtimer 不断更新,为此我使用了一个工作 Qthread,这是我的代码:
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget
from PyQt5.QtCore import QThread, QTimer
import sys
import threading
class WorkerThread(QThread):
def run(self):
print("thread started from :" + str(threading.get_ident()))
timer = QTimer(self)
timer.timeout.connect(self.work)
timer.start(5000)
self.exec_()
def work(self):
print("working from :" + str(threading.get_ident()))
QThread.sleep(5)
class MyGui(QWidget):
worker = WorkerThread()
def __init__(self):
super().__init__()
self.initUi()
print("Starting worker from :" + str(threading.get_ident()))
self.worker.start()
def initUi(self):
self.setGeometry(500, 500, 300, 300)
self.pb = QPushButton("Button", self)
self.pb.move(50, 50)
self.show()
app = QApplication(sys.argv)
gui = MyGui()
app.exec_()
Starting worker from :824
thread started from :5916
working from :824
working from :824
最佳答案
答案:在你的情况下,我认为没有必要使用 QThread
.
TL;博士;
我什么时候需要在 GUI 上下文中使用另一个线程?
当某个任务可以阻塞主线程称为GUI线程时,应该只使用一个线程,阻塞是因为任务耗时,导致GUI eventloop无法正常工作。所有现代 GUI 都在一个事件循环中执行,它允许您从键盘、鼠标等操作系统接收通知,还允许您根据用户修改 GUI 的状态。
在你的情况下,我没有看到任何繁重的任务,所以我认为不需要 QThread,我真的不知道你想要定期运行的任务是什么。
假设你有一个消耗大量时间的任务,比如说 30 秒,你必须每半小时做一次,那么线程是必要的。在您的情况下,您想使用 QTimer。
让我们分批进行,QTimer
是一个继承自 QObject
的类, 和 QObject
属于与父级相同的,如果它没有父级,则属于创建它的线程。另一方面,很多时候人们认为 QThread
是Qt的一个线程,但不是,QThread
是一个允许处理本地线程生命周期的类,这在 docs 中有明确说明。 :QThread 类提供了一种与平台无关的方式来 管理线程 .
了解了以上内容,我们来分析一下你的代码:
timer = QTimer(self)
在上面的代码中,self 是 QTimer 的父级,self 是
QThread
, 所以
QTimer
属于
QThread
的父线程或创建 QThread 的地方,而不是创建
QThread
的线程处理。
QThread
被创建:
worker = WorkerThread()
正如我们看到的
QThread
没有父级,则
QThread
属于创建它的线程,即
QThread
属于主线程,因此它的
QTimer
child 也属于主线程。还要注意的是
QThread
的新线程句柄仅具有
run()
的范围method ,如果该方法在别处属于
QThread
所在的字段已创建,以上所有我们看到代码的输出是正确的,并且
QThread.sleep(5)
在主线程上运行导致事件循环崩溃和 GUI 卡住。
QTimer
的父级以便它所属的线程是
run()
之一方法,并在同一方法内移动功函数。另一方面,不必要地创建静态属性是一种不好的做法,考虑到上述结果代码如下:
import sys
import threading
from PyQt5.QtCore import QThread, QTimer
from PyQt5.QtWidgets import QApplication, QPushButton, QWidget
class WorkerThread(QThread):
def run(self):
def work():
print("working from :" + str(threading.get_ident()))
QThread.sleep(5)
print("thread started from :" + str(threading.get_ident()))
timer = QTimer()
timer.timeout.connect(work)
timer.start(10000)
self.exec_()
class MyGui(QWidget):
def __init__(self):
super().__init__()
self.initUi()
self.worker = WorkerThread(self)
print("Starting worker from :" + str(threading.get_ident()))
self.worker.start()
def initUi(self):
self.setGeometry(500, 500, 300, 300)
self.pb = QPushButton("Button", self)
self.pb.move(50, 50)
if __name__ == '__main__':
app = QApplication(sys.argv)
gui = MyGui()
gui.show()
sys.exit(app.exec_())
输出:
Starting worker from :140068367037952
thread started from :140067808999168
working from :140067808999168
working from :140067808999168
观察:
关于python - Qthread 上的 QTimer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52036021/
当(且仅当)我退出我的应用程序时,这些(且仅这些)重复消息出现在命令提示符上: QObject::startTimer: QTimer can only be used with threads st
我有一个 QObject 的子类,称为 myObject,它在构造函数的堆上分配了一个 QTimer 数据成员。 myObject 还有一个插槽,它连接到构造函数中的 QTimer timeout()
考虑以下C++语句(示例from docs): QTimer::singleShot(600000, &app, SLOT(quit())); 如何在.qml JavaScript中执行相同的操作,例
文档中说: In multithreaded applications, you can use QTimer in any thread that has an event loop. To sta
文档中说: In multithreaded applications, you can use QTimer in any thread that has an event loop. To sta
我有一个派生自 QThread 的对象,类定义包括 Q_OBJECT 宏。我在线程中创建了一个计时器,这样我就可以在线程运行时进行一些偶尔的检查;但是,超时事件永远不会发生。 我也试过将计时器设置为单
在 Qt 中,我试图设置一个 QTimer每秒调用一个名为“更新”的函数。这是我的 .cpp 文件: #include "mainwindow.h" #include "ui_mainwindow.h
我刚开始使用 Qt 并了解了 QTimers。不幸的是,他们似乎给出了一个错误,我还没有看到在线描述的这个错误: 错误:C2514:'QTimer':类没有构造函数。 我在 dialog.h 的私有(
我想使用 QTimer 用传感器值更新 GUI。 我尝试了以下非常简单的代码: from pyQt4 import QtCore def f(): try : print ("t
出于测试目的,我有一个简单的设置可以按时间间隔更改标签。似乎信号永远不会发出。我正在使用带有 Qt 插件的 Visual Studio 2010。这是我的设置... Window::Window(QW
我是 QT 的新手。我想弄清楚 QTimer 是如何工作的。我想在每次滴答时打印一些东西。但我无法让它工作。 测试对象.cpp: #include "testobj.h" #include #inc
我考虑过为回调提供额外的参数,但这看起来太复杂了(创建自己的修改后的 QTimer 对象等) 读完 QTimer docs 后我想到的另一件事正在保存 timerID 并检查它,但由于回调中没有任何内
我试图在不同的 QThread 中使用 QTimer,但我无法连接到 QTimer 的 timeout () 插槽。 我做错了什么? 这是我的代码: extern MainWindow *mainCl
这是我的情况: 我已经连接了以下内容: connect(timer, SIGNAL(timeout()), this, SLOT(avg())); timer->start(5000); avg()
我有以下类(class): class MainWindow : public QMainWindow { public: void StartTimer() { timer = new Q
这是我使用 QTimer 的方式: QTimer *timer = new QTimer(this); connect(timer, SIGNAL(timeout()), this, SLOT(upd
我试图让一个 QTimer 对象按时间间隔计数,连续调用一个函数。我遵循了一个例子,我已经设置了间隔,但它似乎并没有再次开始计数。 这是我正在使用的代码片段 QTimer *timer = new Q
我试图让 QTimer 运行,但它从未触发。我发现了一些关于计时器的其他问题,但问题始终是计时器超出范围。在我的小例子中情况并非如此: 我在自定义 QMainWindow 中创建计时器,这是 .h 文
我目前正在尝试制作蛇游戏以了解有关 QT 和 C++ 的更多信息,但是当我尝试自动移动我的 QGraphicsRectItem 项目时,它会改变速度。我的问题有没有更好的方法可以在没有 QTimer
我的程序消耗的 CPU 时间确实比我希望的要多得多(2 台显示器最多占用 80-90%)。我正在使用 Qtimers,其中一些时间短至 2 毫秒。在任何给定时间,我可以让每个显示器运行 12 个以上的
我是一名优秀的程序员,十分优秀!