QTabWidget: QLabel sometimes paints what's on the last tab
-
I have an application in which the central widget is a tab widget. I use many labels throughout the application, on different tabs. I frequently (once per second) update the labels with new text by calling setText().
When I switch tabs, however, the labels occasionally get painted with what's displayed on another tab -- it's almost as if the label is momentarily transparent.
Any ideas on what the problem could be?
Update: this happens on two different Linux machines: one running Fedora, the other Ubuntu. Also I've added a small piece of sample code below which demonstrates the problem.
@Andre: In the example I've provided below, the updating occurs in the GUI thread.
-
From the UI thread, as far as I can tell.
-
Kunashir: I think you're on the right track, in that something funky might be happening with a timer/thread.
I tried sending a signal everytime the data changed, but the problem is the data changes too rapidly (300 times / second) and the GUI becomes unresponsive.
So I receive the data in a separate thread and store the values there; then once per second the GUI (using a QTimer, yes) polls the values and performs all the setText()'s for the labels.
-
Also, just to give more information:
I use currentWidget() to make sure I only setText() on labels that are currently displayed, i.e. that are on the currently displayed tab. What happens, however, is that sometimes the labels seem to paint what was on a previously displayed tab.
-
Here is an example that demonstrates part of the problem, if you switch between Tab1 and Tab2 frequently, you will see that the labels on Tab2 sometimes paint what's on Tab1:
tabwidget-bug.pro
@
QT += core guiTARGET = tabwidget-bug
TEMPLATE = appSOURCES += main.cpp
tabtest.cppHEADERS += tabtest.h
@
tabtest.h:
@
#ifndef TABTEST_H
#define TABTEST_H#include <QtGui/QWidget>
#include <QTabWidget>class QLabel;
class QTimer;
class QTextEdit;class TabTest : public QTabWidget
{
Q_OBJECTpublic:
TabTest(QWidget *parent = 0);
~TabTest();private:
QWidget * widget1; QWidget * widget2; QLabel * testlabel; QLabel * testlabel2; QLabel * testlabel3; QLabel * testlabel4; QLabel * testlabel5; QTextEdit * edit; QTimer * timer;
private slots:
void update_test_label();};
#endif // TABTEST_H
@
main.cpp:
@
#include <QtGui/QApplication>
#include "tabtest.h"int main(int argc, char *argv[])
{
QApplication a(argc, argv);
TabTest w;
w.show();return a.exec();
}
@
tabtest.cpp:
@
#include "tabtest.h"#include <QTextEdit>
#include <QVBoxLayout>
#include <QTimer>
#include <QLabel>TabTest::TabTest(QWidget *parent)
: QTabWidget(parent)
{srand ( time(NULL) ); widget1 = new QWidget; widget2 = new QWidget; testlabel = new QLabel( " 0"); testlabel2 = new QLabel( " 0"); testlabel3 = new QLabel( " 0"); testlabel4 = new QLabel( " 0"); testlabel5 = new QLabel( " 0"); edit = new QTextEdit( "Test" ); QVBoxLayout * layout1 = new QVBoxLayout; QVBoxLayout * layout2 = new QVBoxLayout; layout1->addWidget( edit ); layout2->addWidget( testlabel ); layout2->addWidget( testlabel2 ); layout2->addWidget( testlabel3 ); layout2->addWidget( testlabel4 ); layout2->addWidget( testlabel5 ); widget1->setLayout( layout1 ); widget2->setLayout( layout2 ); addTab( widget1, "Tab1" ); addTab( widget2, "Tab2" ); timer = new QTimer(); connect( timer, SIGNAL( timeout() ), this, SLOT( update_test_label() ) ); timer->start( 1000 );
}
TabTest::~TabTest()
{}
@ -
Oops, missing part of tabtest.cpp:
@
void TabTest::update_test_label() {int i = rand() % 100 + 1; QString s = QString("%1").arg(i,3); testlabel->setText( s ); i = rand() % 100 + 1; s = QString("%1").arg(i,3); testlabel2->setText( s ); i = rand() % 100 + 1; s = QString("%1").arg(i,3); testlabel3->setText( s ); i = rand() % 100 + 1; s = QString("%1").arg(i,3); testlabel4->setText( s ); i = rand() % 100 + 1; s = QString("%1").arg(i,3); testlabel5->setText( s );
}
@