Qt - What is meant by this sentence - qt

At the following web page: http://web.mit.edu/qt-dynamic/www/tutorials-tutorial-t3.html
The following sentence is mentioned:
A widget is clipped by its parent and by the widgets in front of it.
What do we mean by such sentence?
Thanks.

Qt has the concept of parent/child widgets. The parent widget is the container of the child widget, all the way up to the main window widget. So this is just saying that a widget will be clipped by its parent (container) widget. This means it won't extend past its parent's boundaries, but will be cut off if it goes beyond. Likewise, a widget is clipped by any widgets in front of it.

First off: the second part of the sentence is no longer true for Qt >= 4.1 where a parent may paint behind its children.
In graphics, clipping describes the limiting of the painting to a given area. E.g. if you drew a line from (0,0) to (100,100) with a clipping rectangle of (50x50)#(0,0), you'd effectively draw a line only from (0,0) to (50,50), ie. all pixels that would have been painted, but lay outside the clipping region, were discarded.
In Qt, painting can optionally be clipped using QPainter methods, but the painting is always implicitly clipped by the QPaintDevice you're operating on. QWidget is a QPaintDevice, and as such, painting outside of its QWidget::rect() will have no effect (= it will be clipped to rect()).
Now, about the second part of the sentence: In older Qt versions, the child widgets would first fill their area with the background color/image, thus effectively clipping the parent's painting to outside the union of all children's geometries. Since Qt 4.1, this behaviour can be disabled by setting the QWidget::autoFillBackground property to false. Indeed, this happens to be the new default, too.
In the autoFillBackground == false case, the child widgets do no longer erase the parent's drawing acting as their background, except where they actually paint. Take a QLabel as an example: with autoFillBackground == false, it merely paints its text, leaving the parent's drawing to shine through as the label's background.

Related

Qtransform scale and width of pen set in Qpaint of qgraphicsitem

Hello friends I am resizing and rotating QGraphicsItem using setTransform-method of QGraphicsItem, I am drawing QGraphicsItem of any shape in its paint-method, when I scale item using setTransform method border of QGraphicsItem also gets thicker and I am setting name to QGraphicsItem, it also gets bigger as per scaling factor. So is there any method by which I could draw the border of item and name given using drawtext in paint method remains of same pen width that I am specifying.
You need to make a pen cosmetic with pen.setCosmetic(true) and use this pen to draw border. Cosmetic pen's width doesn't depend on applied transformations.
I recommend using QGraphicsSimpleTextItem or QGraphicsTextItem to draw text in the scene. You can disable text transformation by calling textItem->setFlag(QGraphicsItem::ItemIgnoresTransformations);. It may be convinient to make main graphics item the parent of the text item, so that text item is positioned relative to the main item.
Note that reimplementing QGraphicsItem::paint is not necessary in most cases because built-in QGraphicsItem subclasses satisfy variety of needs.

What is the meaning of "the item's view geometry and scene geometry will be maintained separately"?

The documentation for the QGraphicsItem::ItemIgnoresTransformations flag says
The item ignores inherited transformations (i.e., its position is still anchored to its parent, but the parent or view rotation, zoom or shear transformations are ignored). This flag is useful for keeping text label items horizontal and unscaled, so they will still be readable if the view is transformed. When set, the item's view geometry and scene geometry will be maintained separately. You must call deviceTransform() to map coordinates and detect collisions in the view. By default, this flag is disabled. This flag was introduced in Qt 4.3. Note: With this flag set you can still scale the item itself, and that scale transformation will influence the item's children.
Of course I have read the QGraphicsItem details, the QGraphicsScene details, the QGraphicsView details, and the Graphics View Framework.
There are also several questions about the ItemIgnoresTransformations flag like Fixed size QGraphicsItems in multiple views?
But I still do not understand the sentence in bold face. What does it mean ?
The problem that rose this concern is described in PyQt: Moving multiple items with different ItemIgnoresTransformations flags, but maybe this question was too long, or too pyqt oriented at first sight. And it was more about moving items. So here I'm trying to better focus.
Imagine situation that parent is rotated 45 degrees or even have some sheer. Since current item ignores this transformation it stays strait (not rotated).
Now ask question how this impacts on item size and position? Parent may maintain geometry of item (for example by using layout) but it doesn't take into account this flag, so some geometry (which is in parent units) will be set but effectively items scene rect may appear different since item ignores transformation and it is not rotated squeezed zoomed as a parent.
So from parent point of view geometry has some value but form scene point of view it is different.
It would be best if you try to see how it works in practice It is hard to describe problem clearly.

JavaFX: Rectangle with custom bounding rect and paint method

What I want to do:
In PySide, one could override the paintEvent() method of a QWidget to draw a custom widget. The bounding rect can be customized by overriding the boundingRect() method.
How does one do this in JavaFX? My goal is to create a custom Rectangle object, that draws itself smaller than it's bounding rect.
In context:
I'm creating an MS Paint clone in JavaFX. I'm working on the selection box that you use to select/move pixels around. I want the cursor to change to the appropriate resizing cursor when it is near the outside of the selection box.
However, the bounding rect is the same size as the selection box drawn on the screen, so the cursor only changes when it is on top of the box, but not when near. My solution is to set the bounding rect to larger than the actual selection box is, so the cursor change will occur. Then, override it's paintEvent() equivalent to draw a smaller selection box.
Thanks for your help.
I have a similar use case to you, and asked a similiar question here : Drawing transform independent layout bounds in JavaFX.
The JavaFX API is much higher level though than Java2D or PySide (I am assuming from your snippets, because I actually never heard of it ;) ), it does not allow you to override painting of Nodes, nor can you stop a Node from inheriting its parents transform.
This means that you need a seperate Group parallel to your content where you create the selection box and update it according to your needs (content changes etc.).
Example SceneGraph:
Scene
contentGroup
someShapeFromUser
selectionBoxGroup
selectionBoxOfSomeShapeFromUser

Qt overlay(drop-up) box

I am creating a Qt application where I need to display contents in an overlay box(Please refer to the attached image). The box needs to slide up from behind the bottom dock when a button is pressed and slide down by toggling the button. I tried with a QWidget but couldn't achieve what I wanted. Also I don't know how to list the elements in the overlay box. The elements are dynamic or changing.
The widgets stacking order is defined by their order in the QObject hierarchy tree. The first element is the bottom, and every next is on top of the previous. Children are on top of their parents, in widgets confined within their bounds, in QML free.
If you want that sliding element to appear on top of everything else, just put its parent on top of everything else.
After all it is on top of the bottom control bar, which is on top of the playlist, so you have it all worked out for you.
The same applies if you decide to do the wiser thing and use QML instead of QWidget. Animation and states are much easier there. Not to mention more specific designs.

Semi-transparent QWidget over QGLWidget: Strange results

I have a full size QGLWidget which paints the application background using QPainter (might change to native openGL commands in the future).
On top of this QGLWidget I use QWidgets (non-GL) for the user interface elements. These are, for example, QLineEdits and QPushButtons. I put them into a custom painted QWidget which uses semi-transparent background painting. The paintEvents of the QLineEdit and QPushButton are overwritten and use semi-transparent backgrounds, too.
The whole UI should look like the following (This is a screenshot where I disabled OpenGL and used QWidget instead of QGLWidget for the background. Note the semi-transparent top bar which also draws a shadow (within its own region)):
When the QLineEdit has the focus, it should have a higher opacity but still not fully opaque:
So now, with OpenGL enabled (The background then is a QGLWidget), the semi-transparent widgets above don't paint on top of the background but on (it seems to be) uninitialized data. The image shining through the top bar is sometimes the whole window itself and sometimes other windows currently being on my desktop.
This currently looks like the following (In this screenshot, the data on which the semi-transparent painting operations are painted on seems to be an image of the widget itself, having an offset.):
When I wrote text into the line edit (here: "This is some text which has been there before!"), removed it and set the focus back to the background widget (so the magnifier icon and the placeholder text appear), the previously painted things still shine through (Note that the visible border should not be visible anymore, but also still shines through):
So the problem is: Instead of being painted on top of the underlying widgets, the semi-transparent widget is painted on top of the old results, initially being something like "uninitialized memory".
Why does this happen? How can I solve the problem?
Things you should know before answering:
The background scene is a composition of tiles which are rendered off-screen. So it can be painted very fast and repainting of the background for every little change of the overlay isn't problematic.
The top bar is a custom QWidget with manual painting and arrangement of the contained two widgets (the button and line edit).
The two widgets overwrite the paintEvent, only draw their own (semi-transparent) background when they have focus and don't use frames already provided by Qt. So the white border in the second screenshot is drawn in my custom paintEvent.
I want the background and the composition of overlay widgets to be separately implementable. The background is an AbstractMapView which has some concrete map view classes. The whole window is an AbstractView (there are multiple concrete views, too), which contains both a concrete map view and the overlay widgets, composed in a way itself decides. Therefore, I don't want the logic of the overlay widgets to be part of the underlying map view. (I hope you understood this, as it is a bit complicated.)
This sounds like an issue where the GL content (i.e. your background aka the QGLWidget) is not in the Qt context. While I'm not a pro on GL painting with Qt, you may want to look at this discussion regarding GL painting and a QLabel for some direction/potential hints.
http://www.qtcentre.org/threads/40335-QLabel-on-top-of-a-QGLWidget-background-issue
In short, we here at the office use OpenGL painting and offscreen rendering of maps and it's very important to make sure Qt is aware of the pixels so your foreground widgets can have the semi-transparency applied to their backgrounds.
The particular product we use also renders the map in tiles and supports providing the GL output in a buffer (i.e. it's call a snapshot and is provided as a bitmap) at which point we use the paintEvent of a regular QWidget to paint the buffer so that the painted pixels are in Qt context.
You can define a Qframe with Qt::SplashScreen flag as the search box and set its opacity. Put your widgets inside it such as the search textbox and positon it where it should appear on the mainwindow. It will also be a good idea to reposition it as the mainwindow is moved or resized overriding its moveEvent.

Resources