Originally Posted by
jwintz
Of course I have problems when the thread interacts with widgets but I've not yet understood what really is the problem in using widgets in threads
You may be accessing internal QWidget data from within two different threads trashing it effectively.
QCoreApplication:rocessEvents() processes all pending events according to the specified flags until there are no more events to process. Does it actually postpone a computation using a priority queue ?
No, it simply calls the event queue and processes it. You might say that when you call QApplication::exec() its implementation (of course this is a simplification!) looks like:
while(!end) processEvents();
while(!end) processEvents();
To copy to clipboard, switch view to plain text mode
So Wysota, you suggest a general workaround to replace threads ?
Only when it's appropriate
Could you give us a short example ?
I can. Imagine you want to generate a large amount of random numbers and spit it out in your app. In a non-GUI app you would simply do:
int main(){
for(int i=0;i<10000;i++)
printf("%d\n", rand());
return 0;
}
int main(){
for(int i=0;i<10000;i++)
printf("%d\n", rand());
return 0;
}
To copy to clipboard, switch view to plain text mode
In a GUI app you do the same, just redirect the output to some widget. The problem is that it blocks the application until the loop exits.
So an obvious workaround is to use threads:
Q_OBJECT
public:
connect(this,
SIGNAL(generated
(const QString &)), edit,
SLOT(append
(const QString &)));
}
void run(){
for(int i=0;i<10000;i++)
emit generated
(QString::number(rand()));
}
signals:
};
int main(int argc, char **argv){
MyThread thread(&te, &app);
thread.start();
return app.exec();
}
class MyThread : public QThread {
Q_OBJECT
public:
MyThread(QTextEdit *edit, QObject *parent=0) : QThread(parent){
connect(this, SIGNAL(generated(const QString &)), edit, SLOT(append(const QString &)));
}
void run(){
for(int i=0;i<10000;i++)
emit generated(QString::number(rand()));
}
signals:
void generated(const QString &);
};
int main(int argc, char **argv){
QApplication app(argc, argv);
QTextEdit te;
MyThread thread(&te, &app);
thread.start();
return app.exec();
}
To copy to clipboard, switch view to plain text mode
This should work as expected, but there is really no point in using the worker thread as you can achieve the same by:
Q_OBJECT
public:
void start(){
QTimer::singleShot(0,
this,
SLOT(generate
()));
}
public slots:
void generate(){
emit generated
(QString::number(rand()));
if(++cnt<10000)
QTimer::singleShot(0,
this,
SLOT(generate
()));
// "schedule" next timeout immediately }
signals:
private:
int cnt;
};
int main(int argc, char **argv){
Dummy obj;
app.
connect(&obj,
SIGNAL(generated
(const QString &)),
&te,
SLOT(append
(const QString &)));
obj.start();
return app.exec();
}
class Dummy : public QObject {
Q_OBJECT
public:
Dummy() : QObject(){ cnt = 0; }
void start(){
QTimer::singleShot(0, this, SLOT(generate()));
}
public slots:
void generate(){
emit generated(QString::number(rand()));
if(++cnt<10000)
QTimer::singleShot(0, this, SLOT(generate())); // "schedule" next timeout immediately
}
signals:
void generated(const QString &);
private:
int cnt;
};
int main(int argc, char **argv){
QApplication app(argc, argv);
QTextEdit te;
Dummy obj;
app.connect(&obj, SIGNAL(generated(const QString &)), &te, SLOT(append(const QString &)));
obj.start();
return app.exec();
}
To copy to clipboard, switch view to plain text mode
In which case do you suggest using threads (except for network stuff of course), in which case do you suggest to avoid using threads ?
Why except network stuff? You can do network stuff with Qt without or with using threads.
In general threads should be used when the amount of work to do is heavy, can't be split into chunks (if it can, you can use the timer approach), you need many workers, it's not important that the task is executed immediately or in situations when it's simply very convenient to use threads.
DISCLAIMER: The code above was not tested, don't assume it to work
Bookmarks