Search code examples
c++qtqt5qwidgetqpainter

Use custom QPainter to render QWidget


I'm trying to add child widgets to a widget in Qt5. The problem is that the parent widget renders content which is not known to Qt and therefore transparency doesn't work correctly.

To fix this, I need to use a custom QPainter to render the widgets.
In Qt4 I could do this by using the attribute WA_PaintOutsidePaintEvent and rendering the widget in another method.
However, in Qt5 this attribute is gone.

What I've tried:

  • Create a QWidget and override the paintEvent method.
    • Didn't really work (didn't draw anything) but maybe it was only a small mistake. As far as I understood it, this event also doesn't keep the widget from doing its own rendering which is what I want to prevent.
  • Create a QGraphicsView and a QGraphicsScene and add the widgets to the QGraphicsScene
    • Draws the widgets and transparency works. Events (mouse & keyboard), however, do not work.

Solution

  • What I ended up doing and is working fine:

    I'm using a custom top level widget without additional functionality to make mouse and keyboard handling easier.
    This widget doesn't have a parent and is rendered - with its children - into memory using a QImage and overlaid as an image. This way the transparency works. Important here is the WA_NoSystemBackground attribute.
    To make the events work, I've installed an event filter on the application and pass on the events to the widgets in my custom widgets. I'll spare you the details, I'm planning on making the code public later this year anyway and I'll add a link once that's done.

    However, two important notes when passing the events:
    First, to prevent an endless recursive loop because your filter will also catch the events you are sending, I've checked whether the receiving object is a widget and if it is, I simply checked if the topLevelWidget of this widget is an instance of my custom widget class and if it is, the event is ignored.
    Second, simply passing mouse events doesn't make mouse over work. There are separate hover events which you have to take care of yourself.