Results 1 to 16 of 16

Thread: Pixmap in translucent QLabel overlay, distorts screen

Threaded View

Previous Post Previous Post   Next Post Next Post
  1. #1
    Join Date
    Nov 2016
    Location
    Florida, US
    Posts
    27
    Thanks
    7
    Qt products
    Qt5
    Platforms
    Unix/X11

    Default Pixmap in translucent QLabel overlay, distorts screen

    New to QT, and suspect I have a case where I am breaking some rule, or using a bad approach. I realize code would be best, but I have not found a good way to reduce this to a complete, postable example, so with apologies in advance I will try to provide enough code snippets to explain.

    First, let me show you the result. Please see two screen shots attached, one that worked, one that has the failure. They are a display of sheet music, with a momentary overlay showing areas of the screen in color. As you can see, one shows a badly distorted image. At times it is much more distorted than you see here, where the colored areas are not even clearly distinguished.

    The only difference in these two is a delay in creating the overlay (the delay lets it work).

    The Underlying screen structure, before the overlay, looks like this (nesting shown by indents, abbreviated):

    Qt Code:
    1. QWidget* outerLayoutWidget; // outer widget set as central widget in window to hold layout
    2. QVBoxLayout* outerLayout;
    3. QWidget* menuLayoutWidget;
    4. QHBoxLayout* menuLayout;
    5. QWidget* mainMenuLayoutWidget;
    6. QHBoxLayout* mainMenuLayout;
    7. QPushButton* libraryButton;
    8. ...
    9. QWidget* playerMenuLayoutWidget;
    10. QHBoxLayout* playerMenuLayout;
    11. QPushButton* playButton;
    12. QPushButton* firstButton;
    13. ....
    To copy to clipboard, switch view to plain text mode 
    This resides in a QMainWindow class, and outerLayoutWidget is set as the central widget. The various widgets are hidden and visible as needed, and seem to work fine as activity occurs.

    At one point I want to overlay the entire screen (i.e. mainwindow) with a painted overlay for a few seconds. This occurs in code (as action from a button press) which creates quite a few new widgets inside of outerLayout (and with outerLayoutWidget as parent), and then I do this (the variable overlay is defined in the mainwindow class header to match the TipOverlay class).

    Qt Code:
    1. overlay = new TipOverlay(outerLayoutWidget);
    2. overlay->show();
    To copy to clipboard, switch view to plain text mode 

    TipOverlay.h (irrelevant stuff edited):
    Qt Code:
    1. class TipOverlay : public QLabel
    2. {
    3. Q_OBJECT
    4. private:
    5. QWidget* p; // parent;
    6.  
    7. public:
    8. TipOverlay(QWidget* parent); // Call with the widget to overlay
    9. ~TipOverlay();
    10. };
    To copy to clipboard, switch view to plain text mode 

    and in that routine I do a lot of painting into a pixmap and display it (again, simplified a bit)

    Qt Code:
    1. TipOverlay::TipOverlay(QWidget* parent) : QLabel(parent)
    2. {
    3. assert(parent);
    4. p = parent;
    5. this->setGeometry((p->geometry()));
    6. QPixmap tmpPix = QPixmap(p->size());
    7. QPainter painter(&tmpPix);
    8. painter.setOpacity(0.4); // For panels
    9. painter.setFont(QFont("Arial",36,1,false));
    10. .... lots of painting and text code
    11. this->setPixmap(tmpPix);
    12. this->show();
    13. QTimer::singleShot(MUSICALPI_OVERLAY_DURATION / 2,this, // Must be >= duration above
    14. [=]
    15. {
    16. ... nothing here now, eventually animation change
    17. }
    18. );
    19. QTimer::singleShot(MUSICALPI_OVERLAY_DURATION,this, // Must be >= 2* duration above
    20. [=]
    21. {
    22. ... nothing here now, eventually animation change
    23. this->deleteLater();
    24. }
    25. );
    26.  
    27. }
    To copy to clipboard, switch view to plain text mode 

    I originally had animation in this to fade in and out which I thought may be the problem but have stripped it out. The timers right now only call the deleteLater() to remove it.

    As shown above, it almost always gives the distorted view. On a subsequent iteration of the code, however, it works (due to buffering of the images a subsequent iteration takes less computation to produce the underlying screen). Because of this I introduced a half second delay before calling the "new TipOverlay" -- works every time.

    Just to be clear, just before the overlay is created (and without releasing control back to the event processor) the underlying screen has been changed - widgets hidden, background color changed, images resized and overlay is the last thing before releasing control.

    Incidentally, when the timer runs and the overlay deletes itself, the underlying screen is always displayed correctly, i.e. the distortion is not actually a corruption of the rest of the screen.

    Also, if I set opacity to 1 in the overlay, that part painted works fine -- it is the partially-see-through portions that are at issue.

    This leads me to think I am doing something wrong in creating and displaying the overlay widget, perhaps I need to do it in a separate event.

    I HAVE read the information on using QPainter only in a paint event, but I frankly cannot see how to do that, especially once I start using animation. Trying it in the event handler made it hang in what appeared to be a loop, I assume animation changes calling it recursively? I also have read that painting into a QPixmap object that is separately set is an exception to that rule (is it?).

    Some specific questions:

    - Am I right that painting into, and putting a pixmap in a Qlabel outside of a paint event is OK?

    - I am putting this overlay widget as a child of the outermost widget (inside the mainwindow), but am not putting it in the QVBoxLayout that other widgets are in (as I am forcing its layout with the geometry copy). Is that correct?

    - Is there anything wrong with a class inheriting from QLabel producing its own image with QPainter as I have done?

    - Noting that if painted at opacity 1, the overlay looks fine (at least the the parts painted), it is the areas transparent (unpainted) or partially transparent (painted at opacity 0.4) that are distorted -- is that supposed to work? To see-through to a just-changed widget(s) underneath? Do I need to wait in some fashion for that to be rendered before overlaying it? (If so, how to detect it is ready, as I don't want to guess with a time frame).

    I realize this is long (even without complete code) and thank anyone who just got to the bottom, but especially if you might give me a pointer where to look.
    Attached Images Attached Images

Similar Threads

  1. Overlay 2 images in QLabel
    By 2lights in forum Qt Programming
    Replies: 1
    Last Post: 6th August 2013, 21:36
  2. Painting an overlay on a QLabel->QImage
    By papillon in forum Qt Programming
    Replies: 7
    Last Post: 10th July 2012, 09:28
  3. Pixmap updating QLabel
    By Matt in forum Newbie
    Replies: 11
    Last Post: 17th August 2010, 21:11
  4. empty pixmap as a QLabel
    By tommy in forum Qt Programming
    Replies: 16
    Last Post: 11th December 2007, 21:15
  5. Pixmap Overlay
    By ToddAtWSU in forum Qt Programming
    Replies: 5
    Last Post: 22nd June 2006, 20:19

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.