Graphics glitch in QLabel (showing old image data when calling setText())
-
Hi! I have an application that shows images on a QLabel. Every once in a while, no image is available, and the label clears and displays some text ('no image'). I noticed that whenever this happens, a previous image appears on the label for a fraction of a second between the current image and the new text contents.
I tried to setUpdatesEnabled(false) before the setText() call, and reenabling updates after, but the results are the same. I also tried to QPixmapCache::clear(), but I don't think that does what I thought it does and doesn't work anyway.
I recorded a little video of it here: https://www.youtube.com/watch?v=LRZi4hHD29o
The code used in the video is the following (to run this, you would need to add two images, 1.jpg and 2.jpg, to the application directory).
// main.cc #include "button.h" int main(int argc, char *argv[]) { QApplication app(argc, argv); QMainWindow mw; QLabel *l = new QLabel(&mw); l->setFixedSize(300, 300); l->setText("test"); Button *b = new Button(l, &mw); QObject::connect(b, SIGNAL(clicked()), b, SLOT(next())); QGridLayout *layout = new QGridLayout(&mw); layout->addWidget(l); layout->addWidget(b); QWidget *w = new QWidget(&mw); w->setLayout(layout); mw.setCentralWidget(w); mw.show(); return app.exec(); }
//button.h #include <QtGui> class Button : public QPushButton { Q_OBJECT; int count; QLabel *label; QPixmap pm; public: Button(QLabel *l, QWidget *parent = 0) : QPushButton("NEXT", parent), count(0), label(l) {}; public slots: void next() { if (count % 3 == 0) { if (pm.load("1.jpg")) label->setPixmap(pm.scaled(label->size(), Qt::KeepAspectRatio)); } else if (count % 3 == 1) { if (pm.load("2.jpg")) label->setPixmap(pm.scaled(label->size(), Qt::KeepAspectRatio)); } else if (count % 3 == 2) { label->setText("NO IMAGE"); } ++count; }; };
Does anyone have an idea how to solve this? The issue was observed under X11 by the way, I don't know if it happens on other platforms.
Thanks!
-
Hi. Can't access the video, it's private.
-
@Wieland Hi! Sorry, that was my first time on youtube. It should be fixed now. Thanks!
-
I see. That's obviously a bug. The question remains if it's a bug in Qt or somewhere else in the graphics stack. Maybe this bug is already in our bug database. See https://bugreports.qt.io. What graphics driver do you use? The Nvidia drivers caused a lot of problems in the past.
As a workaround, have you tried to assign a null pixmap?
else if (count % 3 == 2) { pm = QPixmap(); label->setPixmap(pm); label->setText("NO IMAGE"); }
-
Thanks for the reply. This is using intel graphics, and unfortunately your workaround does not help. After your message, I've tested the same code from a newer live image and also on my more up-to-date laptop (which has similar hardware) and I can not reproduce the issue in either of these cases. On the affected machine, I tried updating the intel driver and mesa, but this did not solve it, so I guess it probably needs the kernel or qt packages updated as well. Unfortunately, this is not an option at this point.
I've worked around the issue by re-implementing paintEvent() to do something like the following
if (no_pixmap_set) { pos = calculateTextPosition() QPainter::drawText(pos, text); return; } QLabel::paintEvent(event);
Which seems to work just fine. In fact, re-implementing the paintEvent has given me the chance to animate the image changes which looks pretty nice, and it will be easy to simplify the code a bit when all my machines are fully updated and the glitch is gone.
Thanks again!