问题描述
一段时间以来,我现在很高兴能在一个响应迅速的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.htmland 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,螺纹,拉力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!