Qt World Summit: Submit your Presentation

Translucent background - repaint issue Mac

  • Hello,
    Platform: Mac 10.9, Qt 5.2.1 (same with older version from 5, didn't tested 4.8.x)

    I'm struggling with, probably simple, issue of repainting content on translucent window.

    Issue - when widget do have translucent attribute after content change for the child items window dont redraw itself.
    What I want to achieve is to get translucent scene that user can interact with. But currently when item on that scene is moved around scene / view background is not redrawn.

    Because my main implementation is more complicated and this issue can be reproduced on QWidget here is a sample that shows this:

    Simple project, empty, in MainWindow adding new widget like:

    @ TransWidget *w = new TransWidget( );

    TransWidget is just QWidget subclass, in ctr I add label with animation and set translucent attribute like:

    @TransWidget::TransWidget(QWidget *parent) :
    ui(new Ui::TransWidget)

    resize( 400, 400);
    move( QPoint(100, 100));
    setWindowFlags( Qt::FramelessWindowHint);
    setAttribute( Qt::WA_TranslucentBackground, true);
    setAutoFillBackground( false);
    QLabel *l = new QLabel( this);
    l->setText( "Example text");
    l->setAutoFillBackground( false);
    QPropertyAnimation *a = new QPropertyAnimation(l, "geometry");
    a->setDuration( 10000);
    a->setStartValue( l->rect());
    QRect eRect;
    eRect = l->rect();
    eRect.moveTopLeft( this->rect().bottomRight());
    a->setEndValue( eRect);


    Now expected result is:
    QLabel (with text "Example text" will animate from top left corner to bottom right corner of parent widget with translucent background) and on screen I got correct result on WIndows:


    And on MacOSX, with translucent background:


    and macOSX withouth translucent background:


    And the question:
    how to force QWidget to update background with translucent attribute set to true?

    Best regards

  • Lifetime Qt Champion


    That might be a bug (or an unusual use case) You should check the "bug report system":http://bugreports.qt-project.org to see if it's something known

  • Thank You for the suggestion.
    I did checked and Indeed there is issue with this starting from Qt 4.8 or so.
    Like: https://bugreports.qt-project.org/browse/QTBUG-12639
    or https://bugreports.qt-project.org/browse/QTBUG-28531

    There is also path proposed for this one but with unknown reason it's not added (well it was but was also removed later on).

    Any one checked / test patch?

    It seams to me like only working implementation with this is on Win (and maybe on Lin - not tested)... strange because it's so long when it was firstly reported.

  • Lifetime Qt Champion

    When a patch gets and added and removed it generally means that it breaks something while trying to fix something else

  • I suspected that it's the case in this situation.

    In general, as person that is new to MacOoX world, does it means that we cant get translucent background window?

    Maybe there is a wok around this? Native window?

  • Lifetime Qt Champion

    Yes you can but your exact use case triggers that bug. One things you can do however is to add information on the current bug reports (also vote for it).

  • So how would I go about getting translucent background for widget in Qt on Mac?

  • Lifetime Qt Champion

    You already are using it, but why did you disable the background auto fill ?

  • For TransWidget it was for testing - don't change anything

    On qlabel - I want only text no bg from QLabel, but that doesn't change the fat that if autoFill is true then rectangle is "left behind" and when false actual text.

  • I the same problem on Mac when moving from Qt4 to Qt5. I could reproduce it with different projects or code examples. I fixed it by adding this code to my application:

    void MyTransparentWindow::paintEvent( QPaintEvent * /event/ )
    QPainter p( this );

    // Qt5 fail to give us a clear backbuffer...
    p.setCompositionMode( QPainter::CompositionMode_Clear );
    p.fillRect( 0, 0, width(), height(), QColor( 0, 0, 0, 0 ) );
    p.setCompositionMode( QPainter::CompositionMode_SourceOver );
    // end


    This fixed the problem for me when using Qt5.1.1, I haven't check if it's actually fixed in Qt5.2+.

  • sandy.martel

    I experimented earlier with fill Qt::transparent but without composition mode. Setting (only)

    void TransWidget::paintEvent( QPaintEvent * /event/ )
    QPainter p( this );

    p.setCompositionMode( QPainter::CompositionMode_Clear );
    p.fillRect( this->rect(), Qt::transparent );


    resolves problem:

    Qt 5.2.1 - MacOSX 10.9.2

  • Lifetime Qt Champion

    Very nice trick !

    Thanks for sharing :)

  • Thanks a lot for the trick, it works for me!

  • This topic is old, but i face with same problem and tricks won't help me. Im using Qt 5.5
    So i found solution in Telegram app source code.

    1. Set attributes and window flags
      m_widget->setWindowFlags(Qt::FramelessWindowHint | Qt::BypassWindowManagerHint | Qt::Tool | Qt::NoDropShadowWindowHint);
      m_widget->setAttribute(Qt::WA_NoSystemBackground, true);
      m_widget->setAttribute(Qt::WA_TranslucentBackground, true);
    2. In paint event
      QPainter::CompositionMode m = painter.compositionMode();
      painter.fillRect(w->rect(), Qt::black);

Log in to reply