Layout problems when switch from QWidget to QGraphicsItem - qt

I'm switching a timeline viewer from QWidget to QGraphicsItem, because QWidget is too heavy, I got performance issues when there are thousand of QWidgets.
I need Layout Management. But I found QGraphicsItem was so light, that it did't support layout. I should use QGraphicsWidget, but there are many useful QGraphicsItem's subclasses, QGraphicsWidget doesn't have them. I think QGraphicsProxyWidget isn't the answer because it is already too slow when I using QWidgets...
So, is there any way to have a layout with any QGraphicsItem? Or is there a better solution?

QGraphicsLayout and QGraphicsLayoutItem are what you are looking for.
http://doc.qt.io/qt-4.8/qgraphicslayout.html
http://doc.qt.io/qt-4.8/qgraphicslayoutitem.html
Hope that helps.

Related

How to add QWidget to a QGLWidget

What is currently the best way to add a QWidget to a QGLWidget as a child? In this case I want to add a QSlider to QGLWidget, however it seems like half the links on Google point to dead information now so it's tricky working out what the current way to achieve this is.
I did try creating a QSlider as a child and setting the geometry, but that didn't seem to do a lot.
Child widgets don't work with a QGLWidget, that's documented.
Use QOpenGLWidget and the child widgets will work fine. There's nothing special to do in this respect, simply add child widgets, layouts, etc., and it "just works".

QWidget - Always resizing by window size

I have a QTextEdit Control and I want it to resize widh window size always.
My solution is using a timer, but that won't be really elegant, so I thought, there must be a property.
Could you help me? Uncle Google wasn't any help.
Thanks in advance.
P.S.: I've tried to write in proper English, but I'm from germany, so there could be some mistakes. I hope you excuse it.
You could use your Windows resizeEvent to update the size of your QTextEdit.
Read more about the resizeEvent in the QWindow documentation: http://doc.qt.io/qt-5/qwindow.html#resizeEvent
And here is an Example:
void MyQWindow::resizeEvent(QResizeEvent* event)
{
QWindow::resizeEvent(event);
this->resizeTextEdit(); // In this function you update the size
}
Generaly, You can do that just with layouts, just wrap the QTextEdit inside one, (QVBoxLayout or QHBoxLayout for example).
Or if you have a specific case, you can use the method prposed by Mailerdaimon.

Qt: The best procedure to create own QGraphicsScene/s

I'm making fractal creator software. So I need one scene per fractal and these scenes need to be "layered" because of zooming rubber band.
I've already tried to write it the "widget" way, so I had one custom widget called "canvas". In my canvas class I overrided paintEvent, and inside this event I rendered current fractal. Everytime when somebody clicked to menu with another fractal, I called update() method and new fractal was rendered. To zooming I used overriding of mouse events and update() of canvas. At the first time I repainted the whole canvas, but it was very very slow. After that I repainted only the part under the rubber band, but still slow when I'd like to select some bigger area and other problems with repainting.
So I've looked for another way to do it. Layers. I've found the QStackedWidget, but I didn't find way how to make visible both of my layers and the top one to be transparent. After that, I've found QGraphicsScene and this seems to be the best way to do it. But I don't know the correct procedure to do it. Below are two procedures I'm thinking about:
Create QGraphicsView
Instead of the widget, the canvas will be QGraphicsScene
I'll override some QGraphicsScene event (but I don't know which one - drawItems() is obsolete and override update() seems wrong to me, but maybe...)
When other fractal will be chosen, I'll repaint canvas by calling update() the same way as in my "widget" solution
In the foreground layer will be zooming rubber band
or:
Create QGraphicsView
Instead of the widget, the canvas will be QGraphicsScene
Every fractal will be the child of QGraphicsItem
When other fractal will be chosen, I'll remove the old one fractal
item and replace it by new one and probably call invalidate()
In the foreground layer will be zooming rubber band - I think, that
it's common behaviour of the QGraphicsScene isn't it?
Is one of my reasonings correct? Do you suggest anything else? Fractals are complicated in the calculations and It's very important to repaint only if it is necessary. Could you help me, please?
Thank you :-)
Edit: "zooming rubber band" explanation:
I'm sorry for my expression "zooming rubber band". It means scale (zoom) the area below the selection made by the rubber band - zooming the same way as in Photoshop CS5 (for example). And I'd like to know what part of the scene is repainted while selecting this way. If there is repainted whole scene, or the part of the scene below selected area, or there is nothing repainted and rubber band selection is done in separate layer.
I hope my explanation helped :-).
In Qt, a QGraphicsScene can be thought of as a world of items, with a QGraphicsView as a window into that world. Therefore, you should be adding items to the QGraphicsScene, based on QGraphicsItem (or QGraphicsObject if you want signals and slots).
In your situation, I'd create a Fractal class that inherits from QGraphicsItem and add that to the scene. Ensure to override the necessary pure virtual functions such as boundingRect and paint.
Do not calculate the fractal code in the paint function. I suggest the Fractal class stores a QPixmap (or QImage if you're drawing at the pixel level) and render the fractal to this. Then perodically, in the paint function, the Fractal class would render the contents of the QPixmap with a call to painter->drawImage or painter->drawPixmap; whichever is relevant in this case.
As for zooming, your Fractal class can then response to being scaled, appropriately changing the rendering on the internal representation.

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.

Scalable painting of a Qt application

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.

Resources