Qt tip & Trick: Masking Widgets December 13, 2010
Posted by tumaix in planetkde-tomazcanabrava.trackback
Have you ever tried to create an overlay on top of some QWidgets to make them not acessible, but still visible to the user? I’m not saying about setEnabled(false), but to create a semitransparent – mask on top of some widgets with something inside, a modal dialog or so.
I was yesterday at #qt trying to figure out how to do that, aseigo had already told me that it was possible by using a QGraphicsView as the mask widget with a transparent background, so I did this:
[snip]
view->scene()->setSceneRect( w->rect() );
view->setFixedSize( w->size() );
view->setFrameStyle( QFrame::NoFrame );
view->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
view->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
view->setBackgroundRole( QPalette::Window );
view->setBackgroundBrush(QBrush(QColor(122,122,122,122)));
view->setAutoFillBackground( true );
[/sniṕ]
this was doing almost, but not quite, not what I wanted. It correctly paced the QGraphicsView on top of the widgets, no scalling, but it was opaque. then Leo Franchi came to the rescue.
QPalette p = view->palette();
p.setColor( QPalette::Window, Qt::transparent );
view->setPalette( p );
that way, the QGraphicsView was alpha-transparent on top of my widgets, and a nice mask-effect was given.
but beware that this approach does not handle resizing since the item does not belong to any QLayout, not a problem with Qt, since you can manage to make that happen using a eventFilter:
bool KWelcomeWidget::eventFilter( QObject* obj, QEvent* event ){
if( event->type() == QEvent::Resize ) {
QWidget *parentWidget = static_cast<QWidget*>(obj);
QGraphicsView *view = static_cast<QGraphicsView*>(d_ptr->m_part->widget());
view->scene()->setSceneRect( parentWidget->rect() );
view->setFixedSize( parentWidget->size() );
setFixedSize(parentWidget->size());
return false;
}
return QObject::eventFilter( obj, event );
}
If you want something visible but truely not accessible, it’s far easier to put one QWidget above another and set the Qt::WA_TransparentForMouseEvents hint on the top widget. Then it’s visible, but mouse events go through it to the lower widget.
That’s what Yakuake’s visual event overlay does, which is used to display various effects on top of the terminal widget of the Konsole KPart component, since Yakuake can’t access that widget’s paint event.
that way I was just making a mask, but by using a QGraphicsView I can add graphics items on it and make it behave like a modal dialog. for instance to create a “WelcomeDialog” in the middle of the mainWidget
Why do you need a QGraphicsView? Is the same not possible with a simple QWidget?
persons from #qt told me it was not possible 😉
If I am not mistaken, setting the QPalette::Window role of the palette to a color which is not fully opaque should work with all widgets. You don’t need to use a QGraphicsView.
true thing, but by using a QGraphicsView I can use a different collor as the mask
I am not sure what you mean with “a different color as the mask”, the background color can be any color you want.
actually I just followed aseigo and lfranchi while trying to do that ( despite people from #qt saying that was not possible ), aseigo’s and lfranchi’s approach used a QGraphicsView with an alpha background, I tougth it was just that way that way that makes it possible.
Hi,
I’ve made similar things with just using a QWidget and style as backround-color:rgba(0,0,0,100) 😉
Here is the result http://www.vimeo.com/16763092
You can grab the code from http://svn.pardus.org.tr/uludag/trunk/pds/ (it is PyQt)
cool. =D
for mine, I really have to use a QGraphicsView since I’m using plasma to show some stuff, tought.
desenvolver isso em html pode ser tão “xarope” quanto em Qt.
:*
I am trying to create an application in QT in which I want to overlay some buttons on top of a video (which may be played using Phonon media player or Coreplayer media player). Can you help me how should I go about it? I cannot use OpenGL as the embedded device for which I am making this app does not support
you can use a QGraphicsView and use your widgets inside it, thus, making a overlay.
I used QgraphicsView and added my overlay (inherited from QWidget, with a button) as a scene to it. I also added the VideoWidget in which Phonon player is playing the video as a scene to the view. But the area where it overlaps the video area is black. The button on the overlay is seen properly.
I have also tried QStackedLayout but the same output. How to get rid of this black background of the overlay?