PDA

View Full Version : QLabel->setText() sometimes not working



cass
15th May 2010, 08:15
I have created an application with a countdown timer and the number of seconds remaining is displayed in a QLabel widget inside the Graphics View Framework.

In the code below time_label is a QLabel and time_bar is a QProgressBar. Both widgets are wrapped inside a QGraphicsProxyWidgets which are displayed on a QGraphicsScene. The method timerEvent is triggered every 1000ms. The onTestOver() method kills the timer once the time is up. I had left out the irrelevant code on purpose.



void TestPlan::timerEvent(QTimerEvent* tick)
{
time_bar->setValue(time_bar->value()+1);

int max = time_bar->maximum();
int val = time_bar->value();

int time_left = max - val;
qDebug() << time_left;

if (time_left > 0)
{
time_label->setText(tr("%1 seconds remaining").arg(time_left));
}
else
{
time_label->setText(tr("Time is up!"));
onTestOver();
}
}


In Qt Creator's "Application Output" I can see that timerEvent() is called every second so the timer works fine:



14
13
12
11
10
9
8
7
6
5
4
3
2
1
0


However the output on the application whether using Debug or Release build I see the count down from 14 to 12, 11 is skipped, then from 10 to 5, 4 is skipped again, and the from 3 to 0.

I though maybe the QLabel updates slowly and I tried in increase the time per interval to 2000ms, but had the same result. The progressbar which also updates by this method, updates correctly every second. It is just the QLabel that sometimes seems to skip an update.

Any ideas on how I can make the QLabel widget to update correctly?

aamer4yu
15th May 2010, 08:31
Try calling label->update and see if it works..

and you may also post compilable code that has this problem...it wud be easy to verify for others

cass
15th May 2010, 08:47
Try calling label->update and see if it works..
Thank you for the quick response, but label->update() did not work.


you may also post compilable code that has this problem
Unfortunately this code is part of a bigger project that contains thousands of lines of code.

cass
15th May 2010, 09:13
I reproduced the error noticed by the original project to a smaller compilable project:



#include <QtGui>

QGraphicsScene* scene;

class TestPlan: public QObject
{
QProgressBar* time_bar;
QLabel* time_label;
int timer_id;

void timerEvent(QTimerEvent* tick)
{
time_bar->setValue(time_bar->value()+1);

int max = time_bar->maximum();
int val = time_bar->value();

int time_left = max - val;
qDebug() << time_left;

if (time_left > 0)
{
time_label->setText(tr("%1 seconds remaining").arg(time_left));
}
else
{
time_label->setText(tr("Time is up!"));
onTestOver();
}
}

void onTestOver()
{
if (timer_id) killTimer(timer_id);
}

public:
TestPlan()
{
QWidget* widget = new QWidget();
scene->addWidget(widget);

QHBoxLayout* layout = new QHBoxLayout();
widget->setLayout(layout);

time_bar = new QProgressBar(widget);
time_bar->setValue(0);
time_bar->setMaximum(15);
layout->addWidget(time_bar);

time_label = new QLabel(widget);
layout->addWidget(time_label);

timer_id = startTimer(1000);
}
};

int main(int argc, char *argv[])
{
QApplication app(argc, argv);

QWidget* window = new QWidget();

QGridLayout* layout = new QGridLayout(window);
window->setLayout(layout);

scene = new QGraphicsScene(window);
scene->setSceneRect(0,0,window->width(),window->height());

layout->addWidget(new QGraphicsView(scene, window));

TestPlan test;

window->show();

app.exec();

delete window;

return 0;
}

wysota
15th May 2010, 09:51
You are using the timer a bit incorrectly, that's for sure (you can't expect it to fire every exact 1000ms) but I don't know if that's a reason for what you are experiencing. First of all try getting Graphics View architecture out of the equation - reproduce the problem using a plain QLabel.

cass
15th May 2010, 16:06
You are using the timer a bit incorrectly
Then how SHOULD I use the timer?


I don't know if that's a reason for what you are experiencing
The QProgressBar updates fine using the same timer and the same method!


First of all try getting Graphics View architecture out of the equation - reproduce the problem using a plain QLabel.
I know for a small project like this, it is silly to use the Graphics View architecture, but for the original project this is a requirement. I did however removed the Graphics View architecture as you suggested and then the QLabel updated correctly. However the original project still requires the Graphics View architecture for animations and stuff and I was under the impression that Qt 4.6.2 is a stable release.

wysota
15th May 2010, 18:25
Then how SHOULD I use the timer?
You should check the time elapsed instead of bumping the value one by one. To simplify the situation you could use QTimeLine.


The QProgressBar updates fine using the same timer and the same method!
Like I said, I doubt this has any influence on what you observe.


I know for a small project like this, it is silly to use the Graphics View architecture, but for the original project this is a requirement. I did however removed the Graphics View architecture as you suggested and then the QLabel updated correctly. However the original project still requires the Graphics View architecture for animations and stuff and I was under the impression that Qt 4.6.2 is a stable release.

Ok but now we know QLabel::setText() is not the one causing problems.

ChrisW67
16th May 2010, 03:52
The example above works just fine for me on Linux with Qt 4.6.2. No skipped output. Could be a Windows-ism.

Zlatomir
16th May 2010, 13:12
I reproduced the error noticed by the original project to a smaller compilable project: ...

ChrisW67, it works for me too, on Windows (7) and Qt 4.6.2, so that's no windows issue.