- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
关于如何实例化和使用 QThread
的官方文档可以在这里找到:
http://doc.qt.io/qt-5/qthread.html
该文档描述了两种基本方法:(1) 工作对象方法和 (2) QThread
子类方法。我在几篇文章中读到第二种方法不好,所以让我们关注第一种。
编辑:
@ekhumoro 给我指出了以下有趣的文章:https://woboq.com/blog/qthread-you-were-not-doing-so-wrong.html
.显然,两种方法(1)和(2)都有各自的优点:
As a rule of thumb:
If you do not really need an event loop in the thread, you should subclass. If you need an event loop and handle signals and slots within the thread, you may not need to subclass.
class Worker : public QObject
{
Q_OBJECT
public slots:
void doWork(const QString ¶meter) {
QString result;
/* ... here is the expensive or blocking operation ... */
emit resultReady(result);
}
signals:
void resultReady(const QString &result);
};
class Controller : public QObject
{
Q_OBJECT
QThread workerThread;
public:
Controller() {
Worker *worker = new Worker;
worker->moveToThread(&workerThread);
connect(&workerThread, &QThread::finished, worker, &QObject::deleteLater);
connect(this, &Controller::operate, worker, &Worker::doWork);
connect(worker, &Worker::resultReady, this, &Controller::handleResults);
workerThread.start();
}
~Controller() {
workerThread.quit();
workerThread.wait();
}
public slots:
void handleResults(const QString &);
signals:
void operate(const QString &);
};
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
class Worker(QObject):
resultReady = pyqtSignal(str)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
@pyqtSlot(str)
def doWork(self, param):
result = "hello world"
print("foo bar")
# ...here is the expensive or blocking operation... #
self.resultReady.emit(result)
class Controller(QObject):
operate = pyqtSignal(str)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
# 1. Create 'workerThread' and 'worker' objects
# ----------------------------------------------
self.workerThread = QThread()
self.worker = Worker() # <- SEE NOTE(1)
self.worker.moveToThread(self.workerThread)
# 2. Connect all relevant signals
# --------------------------------
self.workerThread.finished.connect(self.worker.deleteLater)
self.workerThread.finished.connect(lambda: print("workerThread finished.")) # <- SEE NOTE(2)
self.operate.connect(self.worker.doWork)
self.worker.resultReady.connect(self.handleResults)
# 3. Start the thread
# --------------------
self.workerThread.start()
def __del__(self):
self.workerThread.quit()
self.workerThread.wait()
@pyqtSlot(str)
def handleResults(self, param):
print(param)
# One way to end application
# ---------------------------
# global app # <- SEE
# app.exit() # NOTE(3)
# Another way to end application
# -------------------------------
self.workerThread.quit() # <- SEE NOTE(4)
self.thread().quit()
if __name__ == '__main__':
app = QCoreApplication([])
controller = Controller()
controller.operate.emit("foo") # <- SEE NOTE(5)
sys.exit(app.exec_())
worker
变量作为构造函数中的局部变量。我实际上是在将 C++ 示例翻译成 Python,并且这个变量也是 C++ 示例中的局部变量。
workerThread
的时间。完成。
global app
和
app.exit()
到
handleResults(..)
投币口。谢谢@Matic 指出这一点!
workerThread
(通过杀死它的事件循环)。第二个代码行结束
mainThread
(也通过杀死它的事件循环)。
doWork()
函数被调用。
global app
和 app.exit()
到handleResults(..)
插槽解决了挂起问题。但是背景究竟发生了什么?这些代码行是否会杀死工作线程?还是主 QApplication 线程? app.exit()
杀死主线程,然后杀死工作线程,因为它是守护进程类型。我发现worker线程是deamon类型的,因为我插入了代码行
print(threading.current_thread())
在
doWork(..)
功能。它打印了
<_DummyThread(Dummy-1, started daemon 9812)>
.当程序退出时,所有守护线程都会自动终止。
QThread::quit()
函数是你的 friend 。官方文档是这样说的:
void
QThread::quit()
Tells the thread's event loop to exit with return code 0 (success). Equivalent to callingQThread::exit(0)
.
This function does nothing if the thread does not have an event loop.
[http://doc.qt.io/qt-5/qthread.html#quit]
handleResults(..)
现在看起来像这样:
@pyqtSlot(str)
def handleResults(self, param):
print(param)
self.workerThread.quit() # Kill the worker thread
self.thread().quit() # Kill the main thread
Controller(..)
的构造函数中插入这一行来检查工作线程的终止情况。 :
self.workerThread.finished.connect(lambda: print("workerThread finished."))
self.thread().finished.connect(lambda: print("mainThread finished."))
QT_VERSION_STR
= 5.10.1)
PYQT_VERSION_STR
= 5.10.1)
最佳答案
您的 Python 示例应用程序需要以某种方式退出,否则它只会在 Controller
之后出现。对象已初始化。
最简单的方法是更改handleResults
在您的示例中执行以下操作:
@pyqtSlot(str)
def handleResults(self, param):
print(param)
global app
app.exit()
关于python - Pyqt5 中的 QThreads : is this the correct C++ to Python translation of the official QThread docs?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50531797/
我想写一些必须在自己的线程中工作的类。我读过这篇文章:http://wiki.qt.io/Threads_Events_QObjects。它建议移动必须在自己的线程中工作的对象,例如: TestCla
在调用所有与 QThread::finished() 信号关联的槽后,QThread::wait() 是否返回(即解除阻塞执行)? 提前致谢。 最佳答案 不,它可能会在与信号 finished() 关
我不是在打电话 exec()在我的代码中,但 timer和 QUdpSocket工作正常。是 exec()用于等待 event接着说? 更新:timer正在工作,因为我没有调用 moveToThrea
如果我创建 QThread 作为局部变量,我发现了一个奇怪的行为。 例如,下面的代码将作为单线程工作,这意味着我需要等待 10 秒,结果才会出来。 但是如果我将线程从局部变量更改为成员变量,它将作为多
I solved my issue by moving the mySubQThread run() into the myQThread run() That said, I still would
一段时间以来,我一直在使用 Qt 开发一个应用程序,在该应用程序中我必须从相机中抓取帧。相机将在与应用程序其余部分不同的线程中运行。我遵循了以下建议: http://mayaposch.wordpre
考虑以下代码片段: class ThreadA::QThread { public: ThreadA() { } void run() { myVariable = n
所以我在构造函数中有以下代码。 m_someObject = new SomeObject(); m_someObject->moveToThread(&m_thread); m_thread.sta
我有 3 个 QThreads 相互调用(全部继承自 QThread。我知道有些人可能建议使用 moveToThread,但暂时忽略这个事实)。简化的代码如下所示: Thread1 类: void T
我想知道 new QThread(this) 和 new QThread() 之间有什么区别,以及这将如何影响我的代码在使用 QThread 时的行为. 最佳答案 QThread 的父级谁执行什么没有
我是 PySide2 的新手。我只是想启动一个示例应用程序并在应用程序启动时启动一个线程,并希望在应用程序关闭时停止该线程。当我关闭应用程序时,我收到以下错误:QThread:在线程仍在运行时销毁。s
关于如何实例化和使用 QThread 的官方文档可以在这里找到: http://doc.qt.io/qt-5/qthread.html 该文档描述了两种基本方法:(1) 工作对象方法和 (2) QTh
我有以下设置: int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // Create the DBM
这是 QTread 的子对象...并在主线程中将其具体化.... 运行时错误如下: ASSERT failure in QCoreApplication::sendEvent: "Cannot sen
在过去的几天里,我一直在尝试使用 QThreads 而不对 QThread 进行子类化的新的首选方法。我遇到的麻烦是当我试图关闭我创建的一组线程时。我经常收到“线程仍在运行时已被销毁”消息(如果我在
我已经创建了这个继承自QThread的类,用于向数据库服务器发送数据,你觉得怎么样?可以改进吗? 谢谢 #ifndef QUERYTHREAD_H#define QUERYTHREAD_H#inclu
我需要在一个线程中进行无限循环。 在 this article作者写道 >you should never ever block the event loop 因为它会阻塞信号槽概念。如何在 QTh
我试图在一个单独的线程中执行一些工作,并在工作完成后停止该线程。 我已经建立了这样的连接 thread.connect( workerClass, SIGNAL( finished() ), SLOT
我有一个快速的问题。我应该创建一个小的多线程程序来从多个传感器获取数据,并且我了解 pthreads 和 qthreads。我可以访问两个图书馆。我个人偏向于使用 Qt,因为它的设计和各种功能。但是,
我需要在主线程上运行 QThread::usleep() (出于各种原因)。 但是,usleep 是受静电保护的。 我想在没有包装器的情况下使用 QThread 的 usleep 函数(我目前正在使用
我是一名优秀的程序员,十分优秀!