有一段时间我现在很狡猾地得到一个大量的时间/ cputime排放动作在一个响应的UI后面运行。不幸的是,我似乎无法让它运行,“我认为”问题是插槽没有在QThread工作器中处理,而是GUI线程。尽管如此,ThreadID仍然有所不同。
我已经读过这个http://doc.trolltech.com/4.6/threads-qobject.html 并使用googel和SO搜索,但没有任何真正帮助我。可能是我看不到的顽固的东西。
下面是我的缩减代码(注意:在与二进制文件相同的文件夹中需要名为“dummy1024x1024.png”的png):
的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() << "";
}
感谢您提供任何帮助/提示/回复
答案 0 :(得分:5)
正确使用QThread
是Qt用户的常见问题。 Qt Labs的blog post很好地解释了这一点。
简而言之,您应该不子类QThread
来包含您要在该线程中运行的代码。您应该将代码包装在QObject
子类中,实例化它并使用QObject::moveToThread
将对象移动到QThread
上下文中,以便在{{1}的上下文中进行处理}}。然后,您可以在QThread
子类中拥有可以安全连接到另一个线程的插槽,但这些插槽将在您期望的上下文中运行。
有些人可能认为,如果您可以轻松地在QObject
方法中完成您想要做的事情并且不需要太多(或任何)外部交互,那么子类QThread
应该没问题,但即使在此简单的情况我赞成一个单独的类来更好地封装。