Reputation: 2061
i'm using QT for the first time and got some problems with refreshing the GUI while adding elements.
The Code looks like:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
PObj obj;
MainWindow mw;
qRegisterMetaType<std::string>();
QObject::connect(&obj, SIGNAL(setText(std::string const&)),
&mw, SLOT(appendText(std::string const&)));
QFuture<void> f1 = QtConcurrent::run(&obj, &PObj::process);
mw.show();
f1.waitForFinished();
return a.exec();
}
With the PObj::process definition:
void PObj::process()
{
for(; ;)
{
sleep(1);
//do work and set text
std::string text = "bla";
emit setText( text );
}
}
And the MainWindow::appendText slot:
void MainWindow::appendText(std::string const& str )
{
ui->listWidget->addItem(QString::fromStdString(str));
}
I've tried placing qApp->processEvents() ,QCoreApplication::processEvents(); ... running wit future in the ThreadPool.
I thought running them with Concurrent::run is enough ?
UPDATE:
The question is, why the GUI isnt refreshed every second a new item is added ?
Upvotes: 0
Views: 70
Reputation: 62777
The f1.waitForFinished();
calls blocks until f1
is finished, as the name implies. This will never happen because you have the infinite loop. So your code will never get to main loop. You can't block the main thread like that! In general, avoid any WaitForXxxx()
methods, especially the GUI thread.
Also, you have no way of stopping the process()
; anyway, so waiting for it to finish doesn't make any sense... You might want to add a way to tell it to stop (such as atomic variable) but anyway, to fix your problem, simply remove the f1.waitForFinished();
line.
To terminate the task nicely, try adding QAtomicInt
flag (not volatile boolean, it won't do), and then change the code like this:
Add member variable to PObj
(should make it private and add setter):
QAtomicInt termianteFlag;
Change main like this:
int main(int argc, char *argv[])
{
///snip
QFuture<void> f1 = QtConcurrent::run(&obj, &PObj::process);
mw.show();
int ret = a.exec();
f1.terminateFlag = 1; // change this to setter method
f1.waitForFinished(); // this is not ideal, will wait for up to a second before exit
}
and
void PObj::process()
{
while(!terminateFlag)
{
sleep(1);
//do work and set text
std::string text = "bla";
emit setText( text );
}
}
Upvotes: 0