qt_gotcha
11th August 2010, 08:19
I have a PlainTextEdit called commandWindow in which I want to display a counter. The counter comes from a thread process. The counter is always on the last line of the PlainTextEdit. I made some test code, the sqrt is to delay the counter:
QString out;
QStringList list;
for (int i = 0; i < 100; i++)
{
double x;
out = commandWindow->toPlainText();
list = out.split("\n");
list.removeLast();
for (int j = 0; j < 10000; j++)
x = sqrt(847239);
list << QString("%1 %2").arg(i).arg(x);
out = list.join("\n");
commandWindow->setPlainText(out);
}
commandWindow->appendPlainText("done\n");
this doesn't display the counter but only updates the commandWIndow whenit is done, it display 99. Also if I comment out the list.removeLast();, it only shows the hunderd lines after it is finished. Suggestions are welcome.
Lesiok
11th August 2010, 08:39
Because for loop is disabling event dispatcher. Just write Yours code like this :
....
commandWindow->setPlainText(out);
QCoreApplication::processEvents();
....
qt_gotcha
13th August 2010, 11:08
actually
QCoreApplication::sendPostedEvents(this, 0);
works better
I have a QProcess (calcProcess) that is linked to a unix programme that gives of blocks of bytes (no readlines, '\n'). It outputs only on the error channel. It outputs first its name, then an umpty line, then a counter that looks like "Execute timstep xxx". That output should be processed in a PlainTextEdit called commandWindow
my code now looks like this for those who are interested:
calcProcess->setReadChannel ( QProcess::StandardError );
connect(calcProcess, SIGNAL(readyReadStandardError()),this, SLOT(readFromStderr()) );
connect(calcProcess, SIGNAL(finished(int)),this, SLOT(finishedModel(int)) );
In the starter function of the process:
{
[...] //get relevant proces info
commandWindow->appendPlainText(" ");
commandWindow->appendPlainText(" ");
commandWindow->appendPlainText(" ");
xlast = commandWindow->document()->lineCount();
// append extra empty lines that will be replaced with the process output
calcProcess->start(prog, args);
}
The function to proces the output on screen is as follows:
void nutshellqt::readFromStderr()
{
QByteArray buf;
buf.clear();
buf = calcProcess->readAllStandardError();
onScreen(QString(buf));
}
void nutshellqt::onScreen(QString buffer)
{
QString output;
QStringList list, listb;
QTimer tT;
tT.setSingleShot(true);
buffer.replace('\r','\n');
// replace unix CR with \n
listb.clear();
listb = buffer.split("\n");
// split process output all out in seperate lines
output = commandWindow->toPlainText();
list = output.split("\n");
// get the lines in the commandWindow, might get slow?
foreach (QString str, listb)
{
if(str.contains("version") )
list.replace(xlast-3,str);
if (str.contains("Exec") )
list.replace(xlast-1,str);
QCoreApplication::sendPostedEvents(this, 0);
// update the plaintextedit with these two actions
tT.start(100);
//delay slightly for readability
output=list.join("\n");
commandWindow->setPlainText(output);
// join new lines and replace the commandWindow
QTextCursor cur = commandWindow->textCursor();
cur.setPosition(output.size());
commandWindow->setTextCursor(cur);
//put the cursor at the end
QCoreApplication::sendPostedEvents(this, 0);
// update plaintextedit with last actions
}
}
Powered by vBulletin® Version 4.2.5 Copyright © 2024 vBulletin Solutions Inc. All rights reserved.