PDA

View Full Version : Lost widget



anli
29th July 2006, 10:18
This is code fragment:



ExcitThread eThread(this, eInfo);
eThread.start(QThread::LowestPriority);

QWidget* widget = new QWidget(this);
QVBoxLayout* l = new QVBoxLayout();
l->addWidget(new QLabel("Working..."));
widget->setLayout(l);
widget->show();

while(eThread.isRunning())
usleep(100);

widget->close();

if(eThread.isOk())
...


The thing is I don't see "Working..." message. The (non GUI) ExcitThread does it's work fine.
Where is "Working..."?

wysota
29th July 2006, 10:23
"Working" is waiting in event queue until you change

while(eThread.isRunning())
usleep(100);
to something more appropriate (like using a timer's signal connected to a slot or QApplication::processEvents), because you are blocking your application in this loop until the thread exists and show() doesn't act immediately but instead posts an event to the event queue.

anli
29th July 2006, 15:13
"Working" is waiting in event queue until you change

while(eThread.isRunning())
usleep(100);
to something more appropriate (like using a timer's signal connected to a slot or QApplication::processEvents), because you are blocking your application in this loop until the thread exists and show() doesn't act immediately but instead posts an event to the event queue.

Frankly speaking, I don't understand the answer completely :-)

At any case I have tried to add to new-thread-initiator few slots (showStatus(), showCritical() and such), and emited appropriate signals inside QThread::run() implementation. It works.

BTW, what is the best place to call connect() for such case? I have done it inside QThread descendant constructor. Last one has QWidget* with mentioned slots as a parameter.

wysota
29th July 2006, 16:01
Why are you using a separate thread here if the main thread doesn't do anything but wait for the other thread?

anli
29th July 2006, 16:18
Why are you using a separate thread here if the main thread doesn't do anything but wait for the other thread?
Now, after separate thread starting, main thread is ready to work with a user, and status bar shows something like "I'm doing this task...". Besides, background thread work can take noticeable period with different result opportunities: OK (for status bar) or critical error (modal dialog). All cases are covered now.

I think, my case is very common case in UI coding. Isn't it?

wysota
29th July 2006, 18:26
while(eThread.isRunning())
usleep(100);

But what is this for? It stops the main thread. And if so, why do you need another thread? You can move its functionality to the main thread and the result will be identical. Better yet, you can split the work you do in the other thread into smaller chunks and use a QTimer with 0 interval to trigger next steps of the process and you'll gain this, that you won't block the event handling and your gui will remain responsive.


I think, my case is very common case in UI coding. Isn't it?
"Common" doesn't mean "proper". You can achieve the same without using a separate thread which only slows down the process.

anli
29th July 2006, 19:02
while(eThread.isRunning())
usleep(100);

But what is this for? It stops the main thread. And if so, why do you need another thread? You can move its functionality to the main thread and the result will be identical. Better yet, you can split the work you do in the other thread into smaller chunks and use a QTimer with 0 interval to trigger next steps of the process and you'll gain this, that you won't block the event handling and your gui will remain responsive.


"Common" doesn't mean "proper". You can achieve the same without using a separate thread which only slows down the process.
I have rewrote the code. My previous msg is in accordans with these fragments:

Starting a thread:


ExcitThread* eThread = new ExcitThread(this, eInfo, this);
eThread->start(QThread::LowestPriority);


QThread implementation:


ExcitThread::ExcitThread(QObject* parent, const ExcitInfo& anInfo, QWidget* aFeedback) : QThread(parent) {
this->info = anInfo;
this->feedback = aFeedback;
connect(this, SIGNAL(showStatus(const QString&)), this->feedback, SLOT(showStatus(const QString&)));
connect(this, SIGNAL(showStatus(const QString&, int)), this->feedback, SLOT(showStatus(const QString&, int)));
connect(this, SIGNAL(showCritical(const QString&)), this->feedback, SLOT(showCritical(const QString&)));
}

void ExcitThread::run() {
emit showStatus("Generating excitation...");
try {
Excitation::generate( this->info.workDir.toStdString(),
this->info.duration,
this->info.sampleRate,
this->info.bitDepth,
this->info.minFreq,
this->info.maxFreq
);
} catch(QLE e) {
emit showCritical(e.msg.c_str());
emit showStatus("Excitation generating failed!", 2000);
return;
}
emit showStatus("Excitation and inverse filter are generated!", 2000);
}


That "while" was with the aim to understand how all this works :-)