Scalable painting of a Qt application - qt

I'm writing a simulation of an embedded device's screen (which contains custom widgets on top of a main QWidget), and while the native size of the screen is 800x600, I want to be able to scale it up and down by dragging the window's corner. Without diddling with grid layouts and stretchers (which won't scale the fonts up/down), how do I accomplish this sort-of zoom? I think part of the solution might be to create a QTransform and somehow inject that into the QWidget for the entire application, or its QPaintDevice or QPaintEngine. I'd like to do this without putting QTransform in each custom widget, just the "main window" QWidget.

This is possible if you are using QGraphicsView as your main display widget. QGraphicsScene now supports widgets as content, so you can literally just scale them.
I believe the alternative is to reimplement the paint() for each widget, and manually set the transform/scale before the painting of child widgets.

Bit of a guess here as I've not tried it... but you could try putting the top-level widget into a QGraphicsView then get the QGraphicsView to do the scaling.
You could then enable OpenGL on the QGraphicsView and have it scaled in hardware so it's nice and fast.

Related

How can I add multiple QPixMap item to a widget?

I have video analysis c++ code and porting to the QT Creator for gui requirements.
We are detecting certain shapes and items from the video stream and adjust their size ie 100x100 and want to display on the screen. We can display through Label but only one QpixMap item.
What is the best way to show detected images automatically on a widget such as last 20 one that autosized?
Is there any a small code sample to start with it to show us the direction?
Thanks.
You could subclass QWidget and reimplement paintEvent to paint whatever you need using QPainter.
See Basic Drawing Example for details:
http://doc.qt.io/qt-5/qtwidgets-painting-basicdrawing-example.html

Creating a permanent static overlay for QGraphicsView scene

I am making an app using Qt (currently 4.8) which displays a literal map from a large number of QGraphicsScene items. I would like to annotate the view with a scale. My requirement for the scale is that it is permanently fixed w.r.t the viewport widget. It needs to be updated whenever the view scale changes (zoom in, etc). There are other possible overlay items as well (compass, etc) so I'd prefer a generic solution.
I have looked at earlier questions around this which suggest:
using the ItemIgnoresTransform
using an overlay pixmap.
I tried IgnoresTransform but that way didn't work right: I couldn't figure out how to fix it in place in (say) the bottom corner of the viewport and was having some difficulty getting the text and lines always displaying in the correct size.
I scrapped that and subclassed QGraphicsView, adding an overlay pixmap by reimplementing the paintEvent (calls original one, then paints the overlay pixmap on top), and an alignment option to indicate where it goes. Coding some pixmap paint code produces a usable scale on the view. Yay! ... but it doesn't work with scrolls - I get "shattered" renderings of the scale all over, or sometimes no scale at all. I think this is because QGraphicsView::scrollViewportBy() uses viewport()->scroll() so I wondered if switching to ViewportSmartUpdate would help, but it doesn't help enough. I'd prefer not to switch to ViewportFullUpdate as that would likely slow the app down too much (there are millions of items in the scene and that would require a full repaint just to move around).
So. Any ideas from here? Would adapting my pixmap code to write to a new mostly-transparent Widget that is overlaid on the viewport be a better way?
Thanks for any help...
Though it may not be the best way of doing this, in the past I've added custom widgets to the window that holds the QGraphicsView / QGraphicsScene, which have the same graphic style as the QGraphicObjects in the scene. When the view is then used to move objects in the scene, or the scene itself, the items on the window remain in the same place.
Hope that helps.

Can't embed OpenGL window into QWidget with XReparentWindow

I'm trying to add better UI for an OpenGL-based program with Qt. Since I can modify that program it's not hard to get the window ID. So I think embedding it into a QWidget would be a good idea. However, it doesn't work like I expected:
After XReparentWindow is called, the OpenGL window lose its decoration, but the position didn't change.
If I use XConfigureWindow to move it to position (0, 0) relative to parent it goes to the top-left corner of the screen, but not the QWidget.
After reparenting, a third window can cover the QWidget, but nothing can cover the OpenGL window.
X11 reported no errors during the whole operation.
It seems the parent of the OpenGL window has been set to the root window instead of my QWidget. What should I do to make it work correctly?
You can replace your current OpenGL window with a QGLWidget which provides an OpenGL context and can be placed into a Qt window directly.
I'm not sure Qt supports XReparentWindow calls like that. The docs don't seem to say it does, so it's probably a bad idea to use it. You could try QWidget::create() instead.

draw qt widget bigger as the mouse hovers over it (overlapping of widgets)

I would like to create a simple effect with my qt gui, but i have no idea how to achieve this.
I have several widgets, that i implemented as subclasses of qwidget. These are part of another widget and live in a layout. When the mouse hovers over these widgets, i want them to appear bigger to highlight the selected one.
This is what i already tried:
Override the paint event, and simply paint it bigger. But then, the other widgets that also live in the same layout overpaint the oversized areas.
I also tried to call the paint function "by hand" from the parent window, to get control over the painting order. But that didnt help either.
I think there has to be a possibility achieving this effect this qt, but i simply dont know how.
Any ideas?
You could either:
create your GUI inside a QGraphicsView, with QGraphicsWidgets and use setScale when the mouse enters or leave the widget, or
use QML.

How to draw QGraphicsItem in a MFC view

I'm starting using Qt in my application. My application is MFC based. I want to draw some QGraphicsItems in my currect MFC view, is it possible?
You may say that it could be done by hosting QGraphicsView with QWinWidget in the MFC view, that don't work, however. Because my Canvas (MFC view) supports zooming and rotating while the QGraphicsView itself don't. When I zooming the QGraphicsItem, the QGraphicsView shows scroll bar instead of enlarging itself.
Any suggestion? Thanks!
Theoretically you could use QGraphicsScene::paint to paint the scene with your QGraphicsItems in the buffer, and then draw it to MFC view, but it does not make any sense...
What is the problem with QGraphicsView anyway? Have you taken a look at the rotate(), scale(), translate() or shear() functions of it?
You can turn off the displaying of scroll bard of QGraphicsView by setting the ScrollBarPolcies to Qt::ScrollBarAlwaysOff. (QGraphicsView is a sub-class of QAbstractScrollArea.)
I am not sure I understand what you mean by rotating QGraphicsView itself instead of the content. Without the scroll bars, I don't see the difference. Also much of the functionality of QGraphicsItem like editing as you indicated, depends on event handling in QGraphicsScene and QGraphicsView to work. I don't think plugging just a QGraphicsItem into the MFC view will do what you want.

Resources