QThread将结果数据传递给MainThread [英] QThread pass result data to MainThread

查看:437
本文介绍了QThread将结果数据传递给MainThread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在考虑如何将结果数据从某些工作线程传递回客户端而不进行复制. Worker驻留在其他线程中,BigData继承了QObject.我的想法是更改数据所有权:

I'm thinking about how to pass result data from some worker thread back to client without copying. Worker lives in other thread and BigData inherits QObject. My idea is to change ownership of data:

class Worker: public QObject
{
    Q_OBJECT
public:
    explicit Worker(QObject *parent = 0): QObject(parent);
signals:
    void resultReady(BigData *data);
public slots:
    void doWork() {
        BigData *data = new BigData(this); // alloc new Data
        while (!dataReady) {
            ... // appending data 
        }
        // Data ready 
        // clearing ownership
        data->setParent(NULL); // data can't be moved to another thread with parent
        data->moveToThread(NULL);
        emit resultReady(data);
    }
};

void MainWindow::handleResult(BigData *data)
{
    if (currentData_) {
        delete currentData_;
    }
    data->setParent(this); // set new ownership

    // works only if data's thread is NULL
    data->moveToThread(QApplication::instance()->thread()); 
    currentData_ = data;
}

看起来不错吗?还是有更合适的方法来做到这一点?

Does it look good? Or there is more proper way to do it?

推荐答案

通常,您使用 moveToThread() 将对象从一个线程推入另一个线程.可以编写data->moveToThread(QApplication::instance()->thread());以避免将线程亲和力设置为NULL,然后从主线程更改它.但是将BigData实例移至主线程后,请注意从工作线程中触摸该QObject .需要注意的另一件事是,在

Usually you use moveToThread() to push an object from one thread to another. This means that instead of doing data->moveToThread(NULL); in your doWork() slot, You can write data->moveToThread(QApplication::instance()->thread()); to avoid setting the thread affinity to NULL and then changing that from the main thread. But after moving the BigData instance to the main thread, Be aware of touching that QObject from the worker thread. Another thing to note about is that, moving a QObject back and forth between threads might cause some side effects, from the docs:

请注意,将重置该对象的所有活动计时器.计时器首先在当前线程中停止,然后在targetThread中重新启动(以相同的间隔).结果,在线程之间不断移动对象可以无限期地延迟计时器事件.

Note that all active timers for the object will be reset. The timers are first stopped in the current thread and restarted (with the same interval) in the targetThread. As a result, constantly moving an object between threads can postpone timer events indefinitely.

仅出于内存管理的目的而继承QObject是过分的. QObject提供了更多内容(自省功能,动态属性,信号/插槽,线程相似性,事件处理,国际化...),您在这里实际上并不需要.

Inherting QObject just for the purpose of memory management is an overkill. QObject provides much more stuff (Introspection capabilities, dynamic properties, signals/slots, thread affinity, event processing, internationalization ...) that you don't really need here.

如果您只对内存管理感兴趣,请 Qt

If you are interested only in memory management, Qt and the C++ standard library have smart pointers that can implement object lifetime management by unique ownership or shared ownership semantics.

有关此答案的示例,该示例将数据加载卸载到全局线程池并显示这些数据准备好后立即在视图中显示.请注意,该模型继承了QObject(因为 QAbstractItemModel 继承了,因为它使用信号/插槽通知数据更改视图),但实际上保留数据的数据结构没有理由继承QObject. .

Have a look at this answer for an example of a model that offloads data loading to the global thread pool and displays these data in the view as soon as they are ready. Notice that the model inherits QObject (because QAbstractItemModel inherits QObject, since it uses signals/slots to inform the view of data changes) but there is no reason for the data structure that actually holds data to inherit QObject. . .

这篇关于QThread将结果数据传递给MainThread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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