How do I resize a QGraphicsView to show the whole QGraphicsScene?
-
@JonB
When I start the application, the main window size is 800x600 pixels (current configuration). When I load an image, it might be a screenshot of 1024*600 pixels coming from my spectrum analyser (too big to be shown in an 800x600 window, so scrollbars are displayed) or it might as well have only 512x349 pixels coming from an old oscilloscope (too small to fit in the window, so white space is shown around the image).That is the reason why one idea was to resize the window every time a new image is shown. I could as well use "fitInView" and scale the image depending on the current view size. Or just accept what Qt does by default, perhaps not the worst solution. I don't have experience with other applications like this. How would you handle this? The Qt examples often handle only simple cases.
-
@JonB
When I start the application, the main window size is 800x600 pixels (current configuration). When I load an image, it might be a screenshot of 1024*600 pixels coming from my spectrum analyser (too big to be shown in an 800x600 window, so scrollbars are displayed) or it might as well have only 512x349 pixels coming from an old oscilloscope (too small to fit in the window, so white space is shown around the image).That is the reason why one idea was to resize the window every time a new image is shown. I could as well use "fitInView" and scale the image depending on the current view size. Or just accept what Qt does by default, perhaps not the worst solution. I don't have experience with other applications like this. How would you handle this? The Qt examples often handle only simple cases.
@DL5EU
(I think) I would allow the user to resize the main window, rather than my program altering it dynamically at runtime. (If you show your pictures in their own popup window each time that's different and you could size that as you create it for each picture, but that's different.) I would usefitInView()
if you are happy shrinking/growing images to fit the viewport, or stick to 1:1 scale and scrollbars if you want to maintain exact resolution. But I am not the greatest UI designer (I regard end-users as irritating but a necessary evil) and I don't know what your application requires, so it's up to you. -
I would also suggest that growing the whole window should, at most, be an option the user can choose. Also, can the user manually resize the window, and if so, would that stop growing it?
But more generally: From what you describe, I believe you would be better served using QtQuick and QML. It can do all you need in an integrated way, it could automatically grow your windows should you want that (QQuickView::SizeViewToRootObject), it offers GPU-accelerated rendering using different backends (DirectX, OpenGL, Vulcan, Metal) without you needing to worry about it.
A number of examples are deployed together with Qt, so you can play around a little and see whether it appeals to you. -
@Asperamanca
I agree that resizing the main window automatically should be an option that the user can choose.However, after some more hours of searching and thinking I have found out that it is in fact very easy to achieve exactly what I want:
void MainWindow::fitWindow() { QSize viewSize = ui->graphicsView->viewport()->size(); resize(size() + (m_image.size() - viewSize)); }
I have also found out how to scale the displayed image by using QTransform. Not being an experienced Qt programmer makes me spending more time searching for a solution than necessary :-)
-
-
@Asperamanca
I agree that resizing the main window automatically should be an option that the user can choose.However, after some more hours of searching and thinking I have found out that it is in fact very easy to achieve exactly what I want:
void MainWindow::fitWindow() { QSize viewSize = ui->graphicsView->viewport()->size(); resize(size() + (m_image.size() - viewSize)); }
I have also found out how to scale the displayed image by using QTransform. Not being an experienced Qt programmer makes me spending more time searching for a solution than necessary :-)
@DL5EU
Yes to yourfitWindow()
code, if it does indeed give what you want.QTransform
lest you do a variety of transformations, but you have to look up what eachm...
variable controls. For just scaling note there is QGraphicsItem::setScale(qreal factor), which could be applied to theQGraphicsPixmapItem
you should now be using for your image item. -
@JonB
Thank you for the hint! Scaling only one item is probably what I need if I have more than one graphics object on the scene and I don't want to scale them all. I will try that. As I said: not being an expert... :-)@DL5EU
There is aQTransfrom
for eachQGraphicsItem
. I think there is one for the scene as a whole, but that's different. Calling a directQGraphicsItem::setScale(qreal factor)
affects only that gfx item. I believe that (as well as dedicated "rotate" or "translate" etc. methods) is just a shortcut/simpler way of manipulating them...
members of the transform, it just addresses the necessary member(s) for you, with a more helpful name. -
@JonB
When I call QGraphicsPixmapItem::setScale(), the item is scaled as expected, but I was not able to find out how I can get the size of the scaled item. boundingRect() remains the same (seems logical as scaling takes place during display).I would like to adjust the scrollbars or adapt the scene size (whatever is necessary) to make the scrollbars appear as soon as a part of the scaled image is invisible (outside of the view/viewport).
Do you know a helpful tutorial that explains all this?
-
@JonB
When I call QGraphicsPixmapItem::setScale(), the item is scaled as expected, but I was not able to find out how I can get the size of the scaled item. boundingRect() remains the same (seems logical as scaling takes place during display).I would like to adjust the scrollbars or adapt the scene size (whatever is necessary) to make the scrollbars appear as soon as a part of the scaled image is invisible (outside of the view/viewport).
Do you know a helpful tutorial that explains all this?
@DL5EU
I don't know the answer to your questions. I would play with whatever you are doing to see what is going on. A clear, minimal example of what you are trying/want/doesn't work posted here or possibly on stackoverflow might get you an answer. You could even try in ChatGPT, not that I would normally recommend it! Have a play withQGraphicsView
methods likecenterOn
,ensureVisible()
andfitInView()
; check how they treat a scaledQGraphicsItem
. I would expect that if part of a (scaled or not) image/item it outside of the view/viewport that would cause scrollbars to appear automatically, unless scaled causes a problem. -
@JonB
When I call QGraphicsPixmapItem::setScale(), the item is scaled as expected, but I was not able to find out how I can get the size of the scaled item. boundingRect() remains the same (seems logical as scaling takes place during display).I would like to adjust the scrollbars or adapt the scene size (whatever is necessary) to make the scrollbars appear as soon as a part of the scaled image is invisible (outside of the view/viewport).
Do you know a helpful tutorial that explains all this?
@DL5EU See documentation of QGraphicsItem::setScale:
The scale is combined with the item's rotation(), transform() and transformations() to map the item's coordinate system to the parent item.
So in order to see the actual size, you can use
auto scaledRectSize = item->mapToParent(item->boundingRect()).boundingRect().size();
- Take the item's boundingRect (in item coordinates)
- Map the rectangle to parent coordinates
- Since the result is a QPolygonF (after all, rotations could be involved in the coordinate transformation), we take QPolygonF's boundingRect (since we know no rotation is actually involved)
- Then we take it's size
Recommended reading: https://doc.qt.io/qt-6/graphicsview.html#the-graphics-view-coordinate-system