Hi,
I'm new to Qt and threading, so I'm probably missing something obvious. I'm trying to use a thread in my application (subclassing QThread), and everything seems to be working. However, when the thread goes into a time consuming operation, my whole GUI freezes up.
I have created a simplified version which is available at http://dsarkar.fhcrc.org/qtthread/. Basically, the main thread and the secondary thread both start a timer (1 and 2 seconds each) that print a message to the console when they timeout(). When I start the application, both sets of messages are printed as expected. There is a menu action that emits a signal that is connected to a slot in the thread making it sleep for 10 seconds. When this is triggered, I would have expected the main thread to keep on going. Instead, both sets of timers stop and the whole GUI freezes up for 10 seconds.
The full code is available on the website. Here are the main parts:
myMainWindow.cpp:
MyMainWindow::MyMainWindow()
{
createActions();
createMenus();
mythread = new MyThread();
connect(timer, SIGNAL(timeout()),
this, SLOT(reportStatus()));
timer->start(2000);
connect(this, SIGNAL(needSleep(unsigned int)),
mythread, SLOT(sleepFor(unsigned int)));
}
void MyMainWindow::reportStatus()
{
printf("Main eventloop timeout event\n");
}
void MyMainWindow::createActions()
{
sleepAct
= new QAction("&Make Thread Sleep",
this);
sleepAct->setShortcut(tr("Ctrl+S"));
connect(sleepAct, SIGNAL(triggered()),
this, SLOT(makeThreadSleep()));
}
void MyMainWindow::makeThreadSleep()
{
emit needSleep(10);
}
MyMainWindow::MyMainWindow()
{
createActions();
createMenus();
mythread = new MyThread();
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()),
this, SLOT(reportStatus()));
timer->start(2000);
connect(this, SIGNAL(needSleep(unsigned int)),
mythread, SLOT(sleepFor(unsigned int)));
}
void MyMainWindow::reportStatus()
{
printf("Main eventloop timeout event\n");
}
void MyMainWindow::createActions()
{
sleepAct = new QAction("&Make Thread Sleep", this);
sleepAct->setShortcut(tr("Ctrl+S"));
connect(sleepAct, SIGNAL(triggered()),
this, SLOT(makeThreadSleep()));
}
void MyMainWindow::makeThreadSleep()
{
emit needSleep(10);
}
To copy to clipboard, switch view to plain text mode
myThread.cpp:
#include <unistd.h>
MyThread
::MyThread(QObject * parent
){
connect(ttimer, SIGNAL(timeout()),
this, SLOT(reportThreadStatus()));
ttimer->start(1000);
return;
}
void MyThread::reportThreadStatus()
{
printf("Thread eventloop timeout event\n");
}
void MyThread::sleepFor(unsigned int t)
{
printf("Thread going to sleep for %d seconds...\n", t);
sleep(t);
printf("Thread waking up...\n");
}
void MyThread::run()
{
exec();
}
#include <unistd.h>
MyThread::MyThread(QObject * parent)
: QThread(parent)
{
QTimer *ttimer = new QTimer(this);
connect(ttimer, SIGNAL(timeout()),
this, SLOT(reportThreadStatus()));
ttimer->start(1000);
return;
}
void MyThread::reportThreadStatus()
{
printf("Thread eventloop timeout event\n");
}
void MyThread::sleepFor(unsigned int t)
{
printf("Thread going to sleep for %d seconds...\n", t);
sleep(t);
printf("Thread waking up...\n");
}
void MyThread::run()
{
exec();
}
To copy to clipboard, switch view to plain text mode
main.cpp:
int main(int argc, char *argv[])
{
MyMainWindow mainWin;
mainWin.show();
mainWin.mythread->start();
return app.exec();
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyMainWindow mainWin;
mainWin.show();
mainWin.mythread->start();
return app.exec();
}
To copy to clipboard, switch view to plain text mode
Does anyone see what I'm doing wrong? Thanks,
-Deepayan
Bookmarks