dra*_*hnr 2 qt multithreading qt4
一段时间以来,我现在非常繁琐,以便在一个响应良好的UI后面运行一个大量的时间/ cputime排放操作.不幸的是,我似乎无法让它运行,"我认为"问题是插槽没有在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();
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
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() << "";
}
Run Code Online (Sandbox Code Playgroud)
感谢您的任何帮助/提示/回复
正确使用QThread是Qt用户的常见问题.Qt Labs的这篇博文很好地解释了它.
总之,你应该不继承QThread包含要在线程中运行代码.您应该将代码包装在QObject子类中,实例化它并使用a QObject::moveToThread将对象移动到QThread上下文中,以便在上下文中进行处理QThread.然后,您可以在QObject子类中拥有可以安全地连接到另一个线程的插槽,但这些插槽将在您期望的上下文中运行.
有些人可能会争辩说,QThread如果您可以轻松地在run()方法内部完成您想要做的事情并且不需要太多(或任何)外部交互,那么子类化应该没问题,但即使在这个简单的情况下,我也倾向于使用单独的类来实现更好的封装.