0
votes

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.
1
show your code pleaseeyllanesc
I don't really see how that's of any use. My code is currently just a lot of experimentation. I can flesh out the examples with a bit more code if that helps but considering that I currently don't really know what I'm doing anymore, I kind of doubt that this would help. What it boils down to is that I need to be able to somehow draw child widgets into a QImage and they still need to be able to get mouse and keyboard events.Stefan Fabian
Then I tried to learn and understand the basics first, then with that knowledge I just experienced. I do not really understand your question, for example that means "The problem is that the parent widget renders content which is not known to Qt". It shows an image of what you want to get to understand you, if you are going to put widget that this inside another widget uses the layouts, in change if you want to change the color, form of the widgets you must override the method paintEvent.eyllanesc
Could you explain what it means to you: add child widgets to a widgeteyllanesc
Well, I have a Qt application which contains a hierarchy of widgets just like probably any qt application. However, one of these widgets renders a 3D image using a 3D library. Because of that the pixel data is not known to Qt so simply adding widgets by doing QWidget *widget = new QWidget(the_3d_render_widget) does add the widget to the tree as one would expect but if you'd now set the background to transparent using widget->setAttribute(Qt::WA_TranslucentBackground) the background of the widget will show what is below the Qt application rather than the content of the 3d widget.Stefan Fabian

1 Answers

0
votes

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.