PDA

View Full Version : Clipping with QRegion(QBitmap());



high_flyer
24th April 2006, 19:28
Hi,

(I thought I posted this post before but I can't find it, so if this is a double post please merge)
I would like to clip the corners or a dialog widget (which is QWidget) in order to have round corners.
Since the size of the dialog can be changed, I need to clip each conrner when the widget is being redrawn. (instead of using a mask on the whole dialog)
I read the docs about clipping, but I didn't quite understand how I can do that...
I know I can clip a region with a QPainter, and I know i can generate any kind of mask using a QRegion that takes a QBitmap as argument.
But what I don't understand is, when I construct QRect(QBitmap()) then how can I position my QRect in x,y position where I want to clip my widget (i.e upper right corner)?

Thanks.

EDIT: I just though maybe setClipRect() and setClipRegion() can be used in conjunction... I'll try that.

high_flyer
24th April 2006, 21:17
Well, I tried the following and its not doing anything...
May be someone can point me to the right way?


QPainter(this);
//m_topLeft is a pixmap of a rounded upper left corener of the dialog
p.setClipping(true);
p.setClipRect(0,0,m_topLeft->width(),m_topLeft->height());
p.setClipRegion(QRegion(QRect(m_topLeft->rect())).subtract(QRegion(QBitmap("panel_top_left_mask.bmp"))));
//m_topLeft->setMask(QBitmap("panel_top_left_mask.bmp")); //testing the QBitmap
if(!m_topLeft->isNull())
p.drawPixmap(0,0,*m_topLeft);


Ther result is that the m_topLeft pixmap gets painted as it does with out the clipping, meaning, that the rest of the upper left corenr is also drawn (and not clipped)....
I made sure QBitmap is not null, with setting it as a mask to the QPixmap, attached is the result - you can see the black background resulting from the correct mask.
I am trying to get the balck area clipped...

Any pointers are welcome.
Thanks.

high_flyer
25th April 2006, 19:28
Ok, maybe I'll try to put my problem in other words...
How can I (or - can I?) use a mask on only a part of a widget?

I guess this is easier to understand... :-)

Thanks.

jacek
25th April 2006, 22:07
How can I (or - can I?) use a mask on only a part of a widget?
IMO you can't.

high_flyer
26th April 2006, 09:47
Hmm... from my experience with Qt, I find it hard to beleive...
This would basically mean it is only possible to have regid cusom shaped widgets...
How would you interpret the following text:
http://doc.trolltech.com/4.1/qpainter.html#clipping


Clipping

QPainter can clip any drawing operation to a rectangle, a region, or a vector path. The current clip is available using the functions clipRegion() and clipPath(). Whether paths or regions are preferred (faster) depends on the underlying paintEngine(). For example, the QImage paint engine prefers paths while the X11 paint engine prefers regions. Setting a clip is done in the painters logical coordinates.

After QPainter's clipping, the paint device may also clip. For example, most widgets clip away the pixels used by child widgets, and most printers clip away an area near the edges of the paper. This additional clipping is not reflected by the return value of clipRegion() or hasClipping().



P.S
Ok, in case you are right, and this is really is not possible, then I just though of a work around for my problem, and would like your opinion:
Since my dialog is a custom made one where the titile bar it self is a cutom widget, I could compose my custom dialog out of 3 parts:
custom title bar
dialog body
custom status bar
This will allow me to construct the title bar and status bar also from 3 widgets, 2 widgets on the sides (where I can apply a fixed mask on the whole side widgets for the round corners) and the middle part.
For this to work, the title bar, dialog body and status bar must be all on the same level, "glued" togeather to look like they are all one widget.
Do you think this could work such, that the movemnets of all parts of the dialog will move at the same time when moved?
Thanks.

jacek
26th April 2006, 14:45
How would you interpret the following text:
QWidget::setMask() does more than clipping --- it also tells the WM where your window really is.


Since my dialog is a custom made one where the titile bar it self is a cutom widget, I could compose my custom dialog out of 3 parts:
I have never tried such thing, but these widgets might fall apart when user moves one of them quickly.

Maybe you could just draw those corners with "transparent" colour?

high_flyer
26th April 2006, 20:27
Maybe you could just draw those corners with "transparent" colour?
Thats an interesting idea.
I'll try it and let you know!

Thanks!

high_flyer
27th April 2006, 17:17
Ok, I tried it, and it _almost_ works.
Almost means, that I gave the dialog a transparent background color, in order to paint the visible parts my self with a visible color.
The problem is that the invisible color come out not really invisible, but black.
Which explains why my previous try (what I posted above with the atteched image) has that outcome, it basically would work if this would have been a child widget on top of its parent.
I am not sure, but I think it has to do with the fact this is a top level dialog, that has no parents (or the parnt is the desktop).
Also I noticed that in the QtQuarterly issue 16, there is quite a lot about the subject, but it alwasy talks about *child* custom shaped widgets, where as I need a top level one, and I could not find any thing that talks about that...

Any help or ideas are very welcome.

Thanks.