[Interest] Issue painting over child widgets

658 views
Skip to first unread message

Murphy, Sean M.

unread,
Nov 17, 2011, 10:50:52 AM11/17/11
to inte...@qt-project.org
I'm trying to create an animation effect for a Photo Booth application, and I'm having trouble getting the animation to paint over child widgets. Here's the setup:

I've got a QMainWindow with 5 QLabels on it and a QPushButton. Call the QLabels "camera" and "image1" - "image4". So the idea is that the "camera" label is always showing a live feed from the digital camera. When the user presses the pushbutton, a timer starts that snaps four images over a period of time and puts those images in labels "image1" - "image4", respectively. This all works fine, but I wanted to make it look a little more polished by adding an animation.

So what I'd like to happen is when the timer fires off to grab an image, I want that image to appear to move from the "camera" label to the correct "image" label. So it should appear to jump off from the "camera" label, float over the top of everything, and land on the desired "image" label.

So my first attempt was to override the paintEvent() of my QMainWindow, create a QPainter and use drawPixmap() to draw my floating image. It's drawing my image, but the image is showing up under all the child widgets, instead of over the top of everything.

Here's my paintEvent() code:

void MainWindow::paintEvent(QPaintEvent *e)
{
QMainWindow::paintEvent(e);
if (showMovingPixmap == true)
{
QPainter painter(this);
painter.setClipping(false);
painter.drawPixmap(movingPixmapXPos,movingPixmapYPos,movingPixmap);
movingPixmapXPos++;
movingPixmapYPos++;
}
}

So what am I missing? Would it be easier to change my application to have a QGraphicsView as the child widget of the QMainWindow, and do everything on a QGraphicsScene?

Sean
_______________________________________________
Interest mailing list
Inte...@qt-project.org
http://lists.qt-project.org/mailman/listinfo/interest

Jason H

unread,
Nov 17, 2011, 11:05:01 AM11/17/11
to Murphy, Sean M., inte...@qt-project.org
Parents paint first, then children.

However what you can do is create the layout of widgets you need, then render() that parent widget to a pixmap, which you then combine in your own overlay class with what ever you need to overlay. You then take the mouse events and send them as needed to the controls.

However with QGraphicsView you can do all that, even more easily.


From: "Murphy, Sean M." <sean....@gd-ais.com>
To: "inte...@qt-project.org" <inte...@qt-project.org>
Sent: Thursday, November 17, 2011 10:50 AM
Subject: [Interest] Issue painting over child widgets

Murphy, Sean M.

unread,
Nov 17, 2011, 1:43:07 PM11/17/11
to inte...@qt-project.org

Can you explain a little more your render() idea?  I’m assuming you mean I take my entire application, render it to a pixmap, and somehow paint that over the top of all the real widgets?  So the user would always be looking at a picture of what my application looks like?  If so, I’m still a bit confused by how I’d render this pixmap on top of the existing widgets, since that’s fundamentally the only issue I’m having with my current implementation.

 

As far as the QGraphicsView technique, I’m all set with that.  It’s just not the path I went down initially, so I was hoping there was just some sort of “PaintOverChildren” flag that I needed to set that would fix my issue with one line of code, without having to transition everything over to the GraphicsView framework.

 

Sean

Bill Crocker

unread,
Nov 17, 2011, 1:51:24 PM11/17/11
to inte...@qt-project.org

How about:

1 - Place a widget over the label widgets in question.

2 - setAttribute(Qt::WA_TransparentForMouseEvents,true);
so that it becomes transparent to mouse events.

3 - Use a transparent background so you can see the widgets beneath.

4 - Draw (animation) on it whatever you want to appear floating
above the widgets beneath and violating the otherwise rigid
rectangular widget boundaries.

Bill

> Inte...@qt-project.org <mailto:Inte...@qt-project.org>
> http://lists.qt-project.org/mailman/listinfo/interest

Murphy, Sean M.

unread,
Nov 17, 2011, 3:40:42 PM11/17/11
to inte...@qt-project.org
Ok, so how do I go about step #1 correctly? My current application has one top-level layout, with all my widgets inside the layout. Ideally, I'd like to have my application be resizable: allowing the QLayout to take care of my visible widgets. So how do I get the invisible widget you're proposing to overlay the "real" widgets, as the application resizes?

I'm a little blind to how I go about putting a widget above another widget. Assuming I can get step #1 figured out, steps 2-4 look pretty simple...

Sean

Bill Crocker

unread,
Nov 17, 2011, 3:48:14 PM11/17/11
to inte...@qt-project.org
Murphy, Sean M. wrote:
> Ok, so how do I go about step #1 correctly? My current application has one top-level layout, with all my widgets inside the layout. Ideally, I'd like to have my application be resizable: allowing the QLayout to take care of my visible widgets. So how do I get the invisible widget you're proposing to overlay the "real" widgets, as the application resizes?
>

Something like:

Create the overlay widget as an independent child of the top level widget (not the widgets layout).
Raise it to the top of the stack.
Manually move() and resize() it to fit the parent.
Overload the parents ::resize event handler and re-adjust it there as well.
In the Overlay::paintEvent Draw a big X from corner to corner of the rect()
to prove that it is being resized properly as you resize the parent.

Bill

Murphy, Sean M.

unread,
Nov 17, 2011, 4:28:19 PM11/17/11
to inte...@qt-project.org
>Create the overlay widget as an independent child of the top level
>widget (not the widgets layout).

My original layout was done in Designer, but I assume I can't do this step in Designer, I must do it in my MainWindow's constructor?

>Raise it to the top of the stack.

This step seems to be my sticking point. How do I manipulate the order of the QObject/QWidget stack? The only semi-relevant function I see is QObject::children(), but that returns a const QObjectList&, so I don't see how I can manipulate it...

>Manually move() and resize() it to fit the parent.
>Overload the parents ::resize event handler and re-adjust it there as
>well.
>In the Overlay::paintEvent Draw a big X from corner to corner of the
>rect() to prove that it is being resized properly as you resize the
>parent.

These parts I get!
Sean

Murphy, Sean M.

unread,
Nov 17, 2011, 4:34:40 PM11/17/11
to inte...@qt-project.org
Answering my own question:

>>Create the overlay widget as an independent child of the top level
>>widget (not the widgets layout).
>
>My original layout was done in Designer, but I assume I can't do this
>step in Designer, I must do it in my MainWindow's constructor?
>
>>Raise it to the top of the stack.
>
>This step seems to be my sticking point. How do I manipulate the order
>of the QObject/QWidget stack? The only semi-relevant function I see is
>QObject::children(), but that returns a const QObjectList&, so I don't
>see how I can manipulate it...

So in my MainWindow constructor, I just added a QLabel as a child of centralWidget(), and this appears to put it on top of all the other widgets, so I think I've got the behavior I'm looking for...

Thanks for all the assistance!


Sean
_______________________________________________
Interest mailing list
Inte...@qt-project.org

http://lists.qt-project.org/mailman/listinfo/interest

Jason H

unread,
Nov 17, 2011, 4:40:55 PM11/17/11
to Murphy, Sean M., inte...@qt-project.org
raise()?


Sent: Thursday, November 17, 2011 4:28 PM

Subject: Re: [Interest] Issue painting over child widgets

Jason H

unread,
Nov 17, 2011, 4:00:32 PM11/17/11
to Murphy, Sean M., inte...@qt-project.org
I've not done it but I'd start by making it to be a child of the root window, but not in a layout. Since there is only one root layout, you'll have to manage the size of it yourself.


Sent: Thursday, November 17, 2011 3:40 PM

Subject: Re: [Interest] Issue painting over child widgets

Bill Crocker

unread,
Nov 17, 2011, 7:21:47 PM11/17/11
to inte...@qt-project.org
Jason H wrote:
> raise()?

>
> >Raise it to the top of the stack.
>
> This step seems to be my sticking point. How do I manipulate the order
> of the QObject/QWidget stack? The only semi-relevant function I see is
> QObject::children(), but that returns a const QObjectList&, so I don't
> see how I can manipulate it...
>

Yes, QWidget::raise()

Bill

Murphy, Sean M.

unread,
Nov 18, 2011, 10:00:40 AM11/18/11
to inte...@qt-project.org
>> raise()?
>>
>> >Raise it to the top of the stack.
>>
>> This step seems to be my sticking point. How do I manipulate the
>order
>> of the QObject/QWidget stack? The only semi-relevant function I see
>is
>> QObject::children(), but that returns a const QObjectList&, so I don't
>> see how I can manipulate it...
>>
>
>Yes, QWidget::raise()

Ahh, I was looking in the wrong place. For some reason, when Jason said "the stack", I assumed that he meant the QObject stack, so I started poking through the QObject functions. I have no idea why my brain went to QObject since everything we're talking about is QWidget...

Sean

Reply all
Reply to author
Forward
0 new messages