depuis un certain temps, je suis fiddly maintenant pour obtenir une énorme action de vidange temps/cputime derrière une interface utilisateur répondante. Malheureusement, je n'arrive pas à le faire fonctionner et "je pense" le problème est que le slot n'est pas traité dans le worker QThread mais le thread graphique. Les ThreadID diffèrent comme prévu cependant.QThread, enfilé, rly?
Je l'ai déjà lu http://doc.trolltech.com/4.6/threads-qobject.html et utilisé recherche googel et SO mais rien qui m'a vraiment aidé. Probablement son quelque chose de têtu que je ne vois pas.
Ci-dessous mon code dénudation (Note: un .png nommé "dummy1024x1024.png" est nécessaire dans le même dossier que le fichier binaire):
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();
}
factice . 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() << "";
}
Merci pour toute aide/conseil/réponse
il y avait un article dans le "Linux Magazin" allemand, à propos de ce problème. Et il y a du code disponible sur github pour les workerthreads qui fonctionnent correctement avec les signaux/slots. Voir ici: http://github.com/picaschaf/Qt-Worker-Thread Cela pourrait être ce que vous cherchez. – smerlin
Merci pour cette information, je lis habituellement le LinuxMagazine mais il me semble que j'ai raté ça. J'ai fait le code ci-dessus basé sur ce que la documentation Qt et les exemples m'ont dit. Malheureusement, la documentation QThread est l'une des pires parties du Qt Doc. – drahnr