PDA

View Full Version : Multiple QGraphicsEffects and subclassing



JonnyJP
29th March 2012, 16:54
Hi,
I need to have irregular shaped buttons that also have a QGraphicsDropShadowEffect.

I've created a custom QGraphicsEffect which masks a widget to an irregular shape (called a maskEffect). This works fine with any QWidget.

I've also created a custom QWidget which is basically a widget with a QPushButton inside it that is stretched to fill the widget, called myWidget. If I apply my maskEffect to the button inside myWidget and the QGraphicsDropShadowEffect to myWidget itself I have an irregular shaped button with the correct drop shadow that follows the shape of the button.

That works because the QPushButton is mapped and the QWidget has no background so the drop shadow effect is applied to what is rendered, i.e. the masked QPushButton.

With me so far? Good.

The problem I'm having is I need myWidget to inherit from QPushButton and not QWidget. Since it is essentially just a QPushButton (but with an irregular shape) it should have the same functions / signals and slots etc.

I can't see how to do this at the moment since the QPushButton is inside the QWidget. If I try to swap this round I end up losing at least one of the QGraphicsEffects.

I imagine I would need to re-implement the paint event of QPushButton for myWidget, but then I'll still only have the outer widget to apply a single graphics effect to.

Any ideas?

Spitfire
30th March 2012, 15:39
What about using QWidget::setMask() (http://doc.qt.nokia.com/4.7-snapshot/qwidget.html#setMask) on the button to give it a shape instead of funky effect and setting the shadow using a setGraphicsEffect()?

JonnyJP
2nd April 2012, 15:53
Thanks.

The problem with setMask is the edges aren't anti-aliased and I couldn't work out how to do this otherwise it would seem like the best solution.

I'm currently using a QPainterPath for the masking graphics effect, which masks the inner button and anti-aliases the edges.

Can you use a QPainterPath with setmask?

Spitfire
2nd April 2012, 16:27
You can use painter path (indirectly) with set mask:

QWidget::setMask( QPainterPath::toFillPolygon().toPolygon() );

But this will result in the same issue - edges will not be antialiased.

As far as I know only way to have aliased edges is to draw them using QPainter.
If you don't want to do that, maybe you could combine both effects into one shadow_and_shape effect?