PDA

View Full Version : How to change Qlabel text color (QPalette not working, Stylesheet too slow)



kyotishi
15th April 2013, 14:51
Hi all,

I am working on a QT GUI application, I receive data from a microcontroller through serial at 5Hz and I am updating the GUI accordingaly

I use QLabel to display received values.


everything works fine, except that I want to change the text color of the QLabel when a value exceeds a certain limit, I have one hundered value to updated and using
stylesheet makes the GUI VERY SLOOOW, and if I use QPalette then there is no effect at all (the color is not changed)


here is my two version of the code




//using Stylesheets:

void GUI::checkLimits(double max, float value, QLabel * label){

if ((value > max)
{
label->setStyleSheet(QString::fromUtf8("color: rgb(255, 0, 0);\n"
""));

}else{
label->setStyleSheet(QString::fromUtf8("color: rgb(0, 255, 255);\n"
""));
}
}


//using QPalette:

void GUI::checkLimits(double max, float value, QLabel * label){

QPalette pal = label->palette ();
if ((value > max)
{
pal->setColor(QPalette::WindowText, Qt::red);

}else{
pal->setColor(QPalette::WindowText, Qt::white);
}

label->setPalette (pal);
label->setAutoFillBackground(true);

}


//then call the function for each Qlabel:

//update the measurements as read from the PMU
void Display::updateData()
{

double max1 = 3.3;
double max2 = 5.5;
double max3 = 7.7;

//value 1
//get the received value
value1 = (receivedData->rec1);
//check if the received value exceeds the max allowed value
checkLimits(max1 ,value1, iuGUI->Qlabel1);
//change the text of the label
iuGUI->Qlabel1->setText(QString::number(value));

//value 2
value2 = (receivedData->rec2);
checkLimits(max2 ,value2, iuGUI->Qlabel2);
iuGUI->Qlabel2->setText(QString::number(value));

//value 3
value3 = (receivedData->rec3);
checkLimits(max3 ,value3, iuGUI->Qlabel3);
iuGUI->Qlabel3->setText(QString::number(value));

//etc....repeat the same for all the values...100!!

}

I am using QT 4.7 and running on Windows 7

pradeepreddyg95
15th April 2013, 15:05
use tr function to display text colors.
lineEdit->setText(tr("<font color = red >"+your text+QString("\n")+QString(" </font size = 11 >")));

Santosh Reddy
15th April 2013, 15:10
As such this is the only problem I see


void Display::updateData()
{

double max1 = 3.3;
double max2 = 5.5;
double max3 = 7.7;

//value 1
//get the received value
value1 = (receivedData->rec1);
//check if the received value exceeds the max allowed value
checkLimits(max1 ,value1, iuGUI->Qlabel1);
//change the text of the label
iuGUI->Qlabel1->setText(QString::number(value)); // should this be value1?

//value 2
value2 = (receivedData->rec2);
checkLimits(max2 ,value2, iuGUI->Qlabel2);
iuGUI->Qlabel2->setText(QString::number(value));// should this be value2?

//value 3
value3 = (receivedData->rec3);
checkLimits(max3 ,value3, iuGUI->Qlabel3);
iuGUI->Qlabel3->setText(QString::number(value));// should this be value3?

//etc....repeat the same for all the values...100!!

}


How often you call updateData(), and from where? (5Hz will be 200 ms), do you call once every 200 ms?

d_stranz
15th April 2013, 18:25
How often you call updateData(), and from where? (5Hz will be 200 ms), do you call once every 200 ms?

What Santosh is talking about is this: if you are calling updateData() from within a loop that is monitoring your signal, and your never get out of that loop to permit the Qt event loop to process pending events, then none of the changes to your labels will appear. Once every 200 ms is plenty of time to update the text and color of a label if you allow the event loop to run.

kyotishi
16th April 2013, 07:11
Once I receive data (every 200ms) a signal is fired and update function is called...I can see the change in text but the change of color is what driving me crazy
it is either (no effect with qpalatte) or too slow with stylesheets...

I don't know if the no effect of qpalatte is due to Windows 7?

I really appreciate your replies

more details: a decoder class is firing the signal, and update function is called , update function resides in the GUI class

Santosh Reddy
16th April 2013, 08:58
Please refer the QPalette documentation, it has few warnings and notes about how not to use the QPalette, when QWidget's palette will be ignored.

ChrisW67
16th April 2013, 09:30
There must be something else going on. This test program updates 100 widgets using style sheets in (typically) less than 10 milliseconds and it has to generate random data also. Is it slow on your machine?


#include <QtGui>
#include <QDebug>

double drand() {
return (double)qrand()/(double)RAND_MAX;
}

class Widget: public QWidget
{
Q_OBJECT
QList<QLabel*> labels;
QList<double> maxima;

public:
explicit Widget(QWidget *p = 0): QWidget(p)
{
QGridLayout *layout = new QGridLayout(this);
for (int r = 0; r < 10; ++r) {
for (int c = 0; c < 10; ++c) {
QLabel *label = new QLabel("0", this);
layout->addWidget(label, r, c);
labels << label;
maxima << drand(); // a fake threshold value
}
}

QTimer *timer = new QTimer;
connect(timer, SIGNAL(timeout()), SLOT(updateData()));
timer->start(200);
}

public slots:

void updateData() {
static const QString red("color: rgb(255, 0, 0);");
static const QString blue("color: rgb(0, 0, 255);");

QTime time;
time.start();
for (int i = 0; i < labels.size(); ++i) {
QLabel * const label = labels.at(i);
const double d = drand(); // fake data
label->setText(QString::number(d, 'f', 3));
if (d > maxima.at(i))
label->setStyleSheet(red);
else
label->setStyleSheet(blue);
}
qDebug() << time.elapsed();
}
};


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

Widget w;
w.show();

return app.exec();;
}
#include "main.moc"


There are a few obvious slow downs in your code. The style sheet fragments as constant and need only be created once. Your solution constructs a new QString every time and does an unnecessary conversion using fromUtf8(). You also make a function call to test the maximum, with the three parameters being copied in the process. Your data is a single precision number and you are comparing to a double maximum which causes a type conversion. If the maxima are constant declare them as such and let the compiler wring a few cycles out for you. The calls to setAutoFillBackground() are unneeded and may interfere with style sheets. If you really need it set it once on the widget and don't set it again.