QThread,螺纹,拉力? [英] QThread, threaded, rly?

查看:98
本文介绍了QThread,螺纹,拉力?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一段时间以来,我现在很高兴能在一个响应迅速的UI后面运行大量的时间/CPU消耗操作.不幸的是,我似乎无法使其运行,并且我认为"问题是,该插槽不是在QThread worker中处理而是在GUI线程中处理.不过,ThreadID与预期的有所不同.

for some time I am fiddly now to get a massive time/cputime drain action running behind a nicly responding UI. Unfortunatly I can't seem to get it running and "I think" the problem is that the slot is not processed in the QThread worker but the GUI thread. The ThreadIDs differ as expected though.

我已经阅读了 http://doc.trolltech.com/4.6/threads- qobject.html 并使用了googel和SO搜索功能,但没有什么真正帮助了我.可能是我看不到的东西.

I allready read this http://doc.trolltech.com/4.6/threads-qobject.html and used googel and SO search but nothing that really helped me. Probably its something stubborn I just don't see.

下面是我的缩减代码(注意:与二进制文件相同的文件夹中必须有一个名为"dummy1024x1024.png"的png):

Below is my cutdown code (Note: a png named "dummy1024x1024.png" is required in the same folder as the binary):

main.cpp

#include <QtGui>
#include "dummy.h"

int main(int argc, char** argv)
{
    QApplication app(argc, argv);
    Dummy d(NULL);
    d.show();
    qDebug() << "App thread " <<  QThread::currentThreadId();
    return app.exec();
}

dummy.h

#ifndef DUMMY_H
#define DUMMY_H

#include <QWidget>
#include <QVBoxLayout>
#include <QPushButton>

#include "workerthread.h"

class Dummy : public QWidget
{
Q_OBJECT
public:
    explicit Dummy(QWidget *parent = 0);
    virtual ~Dummy();
private:
    QVBoxLayout* m_layout;
    QPushButton* m_dummy[3];
    QPushButton* m_shootcalc;
    WorkerThread* m_work;
signals:

public slots:

};

#endif // DUMMY_H

dummy.cpp

#include "dummy.h"

Dummy::Dummy(QWidget *parent) :
    QWidget(parent)
{
    m_work = new WorkerThread(this);
    m_work->start();

    m_shootcalc = new QPushButton("Calc!", this);
    connect(m_shootcalc, SIGNAL(clicked()), m_work, SLOT(expensiveCalc()), Qt::QueuedConnection);

    m_dummy[0] = new QPushButton("Dummy [0]", this);
    m_dummy[1] = new QPushButton("Dummy [1]", this);
    m_dummy[2] = new QPushButton("Dummy [2]", this);

    m_layout = new QVBoxLayout(this);
    m_layout->addWidget(m_shootcalc);
    m_layout->addWidget(m_dummy[0]);
    m_layout->addWidget(m_dummy[1]);
    m_layout->addWidget(m_dummy[2]);
    setLayout(m_layout);
}


Dummy::~Dummy()
{
    m_work->quit();
    m_work->wait();
    m_work->deleteLater();
    m_work = NULL;
}

workerthread.h

#ifndef WORKERTHREAD_H
#define WORKERTHREAD_H

#include <QThread>
#include <QPixmap>
#include <QDebug>

class WorkerThread : public QThread
{
Q_OBJECT
public:
    explicit WorkerThread(QObject *parent = 0);
protected:
    virtual void run();
signals:

public slots:
    void expensiveCalc();
};

#endif // WORKERTHREAD_H

workerthread.cpp

#include "workerthread.h"

WorkerThread::WorkerThread(QObject *parent) :
    QThread(parent)
{
}


void WorkerThread::run()
{
    qDebug() << "Thread start << " << QThread::currentThreadId();
    exec();
    qDebug() << "Thread stop << " << QThread::currentThreadId();
}

void WorkerThread::expensiveCalc()
{
    qDebug() << "start pixie loading.... " << QThread::currentThreadId();
    QPixmap* pixies[16384];
    for (int i=0; i<16384; ++i)
    {
        pixies[i] = new QPixmap("./dummy1024x1024.png");
        if (i>0)
            delete pixies[i-1];
        msleep(1);
    }
    delete pixies[16384-1];

    qDebug() << "loaded pixies " <<  QThread::currentThreadId();
    qDebug() << "";
    qDebug() << "";
    qDebug() << "";
    qDebug() << "";
}

感谢您的帮助/提示/回复

Thanks for any help/tip/reply

推荐答案

正确使用QThread是Qt用户之间的常见问题. Qt Labs的博客帖子对此进行了解释很好.

Proper usage of QThread is a common problem among Qt users. This blog post at Qt Labs explains it nicely.

简而言之,您应该子类包含要在该线程中运行的代码.您应该将代码包装在QObject子类中,实例化它,然后使用QObject::moveToThread将对象移动到QThread上下文中,以便在该QThread的上下文中进行处理.然后,您可以在QObject子类中具有插槽,这些插槽可以安全地连接到另一个线程,但是可以在您期望的上下文中运行.

In short, you should not subclass QThread to contain code that you want to run in that thread. You should wrap your code up in a QObject subclass, instantiate it and use a QObject::moveToThread to move your object into the QThread context so that processing will occur in the context of that QThread. You can then have slots in your QObject subclass that can safely be connected to another thread but will run in the context you expect.

有人可能会争辩说,如果您可以轻松地将想要执行的操作放入run()方法内部并且不需要太多(或任何)外部交互,则子类化QThread应该很好,但是即使在这种简单情况下,我也会赞成使用单独的类来更好地封装.

Some may argue that subclassing QThread should be fine if you can easily fit what you want to do inside the run() method and don't need much (or any) external interaction but even in this simple case I would favor a separate class for better encapsulation.

这篇关于QThread,螺纹,拉力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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