什么是实现 QThread 的正确方法...(请举例...) [英] what is the correct way to implement a QThread... (example please...)

查看:40
本文介绍了什么是实现 QThread 的正确方法...(请举例...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

QThread 的 Qt 文档说从 QThread 创建一个类,并实现 run 方法.

The Qt documentation for QThread says to create a class from QThread, and to implement the run method.

以下摘自 4.7 Qthread 文档...

Below is taken from the 4.7 Qthread documentation...

要创建自己的线程,请子类化 QThread 并重新实现 run().例如:

To create your own threads, subclass QThread and reimplement run(). For example:

 class MyThread : public QThread
 {
 public:
     void run();
 };

 void MyThread::run()
 {
     QTcpSocket socket;
     // connect QTcpSocket's signals somewhere meaningful
     ...
     socket.connectToHost(hostName, portNumber);
     exec();
 }

因此,在我创建的每个线程中,我都这样做了,并且对于大多数事情,它运行良好(我没有在我的任何对象中实现 moveToThread(this) 并且运行良好).

So in every single thread I've created, I've done just that and for most things it works just fine (I do not implement moveToThread(this) in any of my objects and it works great).

上周我遇到了一个障碍(设法绕过我创建对象的地方来解决它)并找到了 关注博文.这里基本上是说子类化 QThread 确实不是正确的方法(并且文档不正确).

I hit a snag last week (managed to get through it by working around where I created my objects) and found the following blog post. Here is basically says that subclassing QThread really isn't the correct way to do it (and that the documentation is incorrect).

这是来自 Qt 开发人员,所以乍一看我很感兴趣,经过进一步思考,同意他的观点.遵循 OO 原则,您真的只想对一个类进行子类化以进一步增强该类...而不仅仅是直接使用类方法...这就是您实例化的原因...

This is coming from a Qt developer so at first glance I was interested and upon further reflection, agree with him. Following OO principles, you really only want to subclass a class to further enhance that class... not to just use the classes methods directly... thats why you instantiate...

假设我想将一个自定义 QObject 类移动到一个线程......什么是正确"的做法?在那篇博文中,他说"他在某处有一个例子……但如果有人能进一步向我解释,我将不胜感激!

Lets say I wanted to move a custom QObject class to a thread... what would be the 'correct' way of doing it? In that blog post, he 'says' he has an example somewhere... but if someone could further explain it to me it'd be greatly appreciated!

更新:

由于这个问题得到了如此多的关注,这里是 4.8 文档的复制和粘贴,其中包含实现 QThread 的正确"方式.

Since this question gets so much attention, here is a copy and paste of the 4.8 documentation with the 'proper' way to implement a QThread.

class Worker : public QObject
 {
     Q_OBJECT
     QThread workerThread;

 public slots:
     void doWork(const QString &parameter) {
         // ...
         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, SIGNAL(finished()), worker, SLOT(deleteLater()));
         connect(this, SIGNAL(operate(QString)), worker, SLOT(doWork(QString)));
         connect(worker, SIGNAL(resultReady(QString)), this, SLOT(handleResults(QString)));
         workerThread.start();
     }
     ~Controller() {
         workerThread.quit();
         workerThread.wait();
     }
 public slots:
     void handleResults(const QString &);
 signals:
     void operate(const QString &);
 };

我仍然认为值得指出的是,它们包含了一个额外的 Worker::workerThread 成员,该成员是不必要的,并且从未在他们的示例中使用过.删除那部分,它是如何在 Qt 中进行线程处理的正确示例.

I still believe that it is worthwhile to point out that they include an extra Worker::workerThread member that is unnecessary and is never used in their example. Remove that piece and it is a proper example of how to do threading in Qt.

推荐答案

我能想到的唯一补充就是进一步说明 QObject 与单个线程有密切关系.这通常是创建 QObject 的线程.所以如果你在app的主线程中创建了一个QObject并且想在另一个线程中使用它,你需要使用moveToThread()来改变亲和度.

About the only thing I can think of to add is to further state that QObjects have an affinity with a single thread. This is usually the thread that creates the QObject. So if you create a QObject in the app's main thread and want to use it in another thread, you need to use moveToThread() to change the affinity.

这样就不必对 QThread 进行子类化并在 run() 方法中创建您的对象,从而使您的东西得到很好的封装.

This saves having to subclass QThread and creating your objects in the run() method, thus keeping your stuff nicely encapsulated.

那篇博文确实包含一个链接到例子.它很短,但它显示了基本思想.创建您的 QObjects,连接您的信号,创建您的 QThread,将您的 QObjects 移动到 QThread 并启动线.信号/槽机制将确保正确和安全地跨越线程边界.

That blog post does include a link to an example. It is pretty short but it shows the basic idea. Create your QObjects, connect your signals, create your QThread, move your QObjects to the QThread and start the thread. The signal/slot mechanisms will ensure that thread boundaries are crossed properly and safely.

如果必须在该机制之外调用对象上的方法,则可能必须引入同步.

You may have to introduce synchronization if you have to call methods on your object outside of that mechanism.

我知道 Qt 有一些其他不错的线程工具可能值得熟悉的线程,但我还没有这样做:)

I know Qt has some other nice threading facilities beyond threads that are probably worth getting familiar with but I have yet to do so :)

这篇关于什么是实现 QThread 的正确方法...(请举例...)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆