How to set flow layout directly in QGraphicsView? Problem understanding QGraphicsView Flow Layout example
-
Hi, i want to have flow layout in my QGraphicsView widget, however i am struggling setting it. I've tried to simply use QGraphicsView::setLayout() but it is not accepting FlowLayout argument because it is expecting to get QLayout* one (Flow Layout is deriving from QGraphicsLayout).
in flow layout example additional window is created within scene in QGraphicsView. How can i do so without creating window but directly in QGraphicsView or QGraphicsScene?
Thanks and best regards :)
-
Just use the example code to create theQFlowLayout
class and set this as your e.g.QMainWindows
layoutLike this (how it's done in the example):// Create layout
FlowLayout *flowLayout = new FlowLayout;// Fill layout with widgets
flowLayout->addWidget(new QPushButton(tr("Short")));
flowLayout->addWidget(new QPushButton(tr("Longer")));
flowLayout->addWidget(new QPushButton(tr("Different text")));
flowLayout->addWidget(new QPushButton(tr("More text")));
flowLayout->addWidget(new QPushButton(tr("Even longer button text")));// set FlowLayout to your main widget
setLayout(flowLayout);
setWindowTitle(tr("Flow Layout"));Edit:
+1 for your username :D
Edit2:
Sorry missed theQGraphicsView
part...
QGraphicsLayouts
andQLayouts
are different. You need to change yourFlowLayout
first. Just derivingQGraphicsLayouts
instead ofQLayout
wont work.
You want this but with aFlowLayout
, right?lol, somehow I got to the wrong page... Ok,there IS actually an
QGraphicsView Flow Layout Example
-
The problem is that there are two flow layouts examples: one (inheriting from QGraphicsLayout) and second (inheriting from QLayout). I already tried to use second one but it is not working on my items within QGraphicsView. So i found out that theres implementation for QGraphicsView but like i mentioned, author made everything work inside of new window.
I am wondering how could i just pass it to the view so it could affect my items just like buttons in other example.
Maybe some fancy reinterpret_cast could make job done? Tried already some casting and didn't work ofc :D -
Ok, I will try again :)
In your
QGraphicsView FlowLayout Example
the flowLayout (derived fromQGraphicsLayout
) is used on anQGraphicsProxyWIDGET
.So you can either use the WIDGET based FlowLayout Example to set the flow layout to your
QGraphicView
(wont affect rendered items on your scene then)
OR
you use the flowLayout on a GraphicsProxyWidget IN your scene. (like in Graphics FLowLayout example) -
@IHatePython said in How to set flow layout directly in QGraphicsView? Problem understanding QGraphicsView Flow Layout example:
I am wondering how could i just pass it to the view so it could affect my items just like buttons in other example.
This is not possible. You can either treat your
QGraphicsView
asQWidget
and then use the widget-based FlowLayout (first example) to put other widgets above the view or you use the second example on aQGraphicWidget
-based widget in your scene to layoutQGraphicItems
in a flowLayout.The first approach would be somewhat like this:
(I've modified the flowLayout widget example)QVBoxLayout *vbox = new QVBoxLayout; FlowLayout *flowLayout = new FlowLayout; QGraphicsView *view = new QGraphicsView; QGraphicsScene *scene = new QGraphicsScene; view->setScene(scene); flowLayout->addWidget(new QPushButton(tr("Short"))); flowLayout->addWidget(new QPushButton(tr("Longer"))); flowLayout->addWidget(new QPushButton(tr("Different text"))); flowLayout->addWidget(new QPushButton(tr("More text"))); flowLayout->addWidget(new QPushButton(tr("Even longer button text"))); // flowLayout to view view->setLayout(flowLayout); vbox->addWidget(view); // Paint BG blue to illustrate the view view->setStyleSheet("background-color: blue;"); setLayout(vbox); setWindowTitle(tr("Flow Layout"));
-
Thank you for your help. Works like a charm. New solution arose so new problems :D As i can see
FlowLayout::addWidget()
is takingQWidget*
argument, but i used to pass to the sceneQGraphicsPixmapItem
, and i have no idea how could i pass it now toaddWidget()
function.I'd like to avoid changing type of
QGraphicsPixmapItem
because i am using flags (i.e.QGraphicsItem::ItemIsSelectable
) and other useful properties. I saw people recommend using pixmaps onQLabels
, however they do not have methods likeQGraphicsPixmapItem
do.Can i somehow set all needed properties to image and cast it or pass as
QWidget
?
What i am trying to achieve:auto item{ new QGraphicsPixmapItem{ QPixmap::fromImage(image) } }; item->setScale(0.1); item->setFlags(QGraphicsItem::ItemIsSelectable | QGraphicsItem::ItemIsMovable); flow_layout->addWidget(item); // cannot initialize a parameter of type 'QLayoutItem *' with an lvalue of type 'QGraphicsPixmapItem *'
-
Then you can not use the widget based FlowLayout. You can only add
QWidgets
and treat them as such.
QGraphicsItem
and its derived classes are notQWidgets
.Maybe you can clarify what your final goal is...
If you really want to use GraphicsItems and use the GraphicsView framework, you could make one scene or screen filling
QGraphic(Proxy)Widget
and add yourQPixmapItem
to it using the GraphicsView FlowLayout. -
@Pl45m4 said in How to set flow layout directly in QGraphicsView? Problem understanding QGraphicsView Flow Layout example:
Maybe you can clarify what your final goal is
Okay haha, so basically i just want to lay images in QGraphicsView using flow layout so if user shrinks window images will relatively stick together. Just like in flow layout example but with
QPixmaps
, notQLabels
.I will play more around
QGraphicsProxyWidget
as you suggest. I already tried using it but i failed since proxy widget'ssetWidget(QWidget*)
takes... QWidget* :)Maybe there is easy way to implement such a function, however it is my first time using GraphicsView so im pretty "shortsighted".
-
With a
QGraphicsProxyWidget
you can actually placeQWidgets
inside aQGraphicsProxyWidget
on your scene, but if you want to keep theQGraphicsItem
-functionality (itemFlags etc.) both ways won't work, I guess...Because the content of a
QGraphicsWidget
andQGraphicsProxyWidget
is still aQWidget
even if it's in aQGraphicsScene
.... andQWidgets
can not useQGraphicsItem
- flags and functions.Maybe you can use another method to select your widgets somehow (
mousePressEvent
) or you create your own flow-"layout" behavior (no real layout) by positioning yourQGraphics(Pixmap)Items
in your scene, like theFlowLayout
would do. But then you have to handle resizing and moving events on your own and re-align all your items manually (by code not by mouse, of course :D ) -
Ohhh i thought so about implementing my own flow layout. Tried to avoid this, because this will be difficult to do, but if there is no other way...
Anyway, thank you. You helped me to understand a little graphics view framework and saved a lot of time.
Best regards!