QScrollArea sizing issue
-
@JNBarchan said in QScrollArea sizing issue:
Hi
first of all
this reads funnyself.vertLayout = QVBoxLayout()
widget.setLayout(self.vertLayout)ahh no. just pyt confusing me . its the same as
VBoxLayout *layout = new QVBoxLayout();
if layout is a class member.
like you give the dialogs layout to the widget ?
Maybe just syntax. They cannot share a layout.anyway, can you try to insert the scrollarea into the dialogs layout ?
self.layout().addWidget( ScrollArea);
The code you link to suffer the same
The dialog have no layout of its own and hence it wont use all of dialogs size.
I think you have same issue as
self.vertLayout = QVBoxLayout()
widget.setLayout(self.vertLayout)creates the layout and give to widget ?
so seems the SELF dialog have no layout and hence wont make
scroll area take up all space. -
@mrjj
I will try your suggestion as soon as I am able.However, although I confess I could be misunderstanding, the reason I didn't think that was necessary is because of http://doc.qt.io/qt-5/qwidget.html#setLayout:
void QWidget::setLayout(QLayout *layout)
An alternative to calling this function is to pass this widget to the layout's constructor.So "to insert the scrollarea into the dialogs layout " you want:
self.layout().addWidget(scrollArea);
and I already have:
scrollArea = QScrollArea(self)
(not justQScrollArea()
constructor) which I understand to do same thing as callingsetLayout(scrollArea)
explicitly, no? -
Hi,
No, not at all. With
scrollArea = QScrollArea(self)
you are just giving it a parent and when you call show on it, it will be shown in the parent viewport.With
setLayout(scrollArea)
, that's just wrong. You can't set a widget as layout.So neither are doing what you want.
In the constructor of your dialog you should have something like:
layout = QVBoxLayout() layout->addWidget(scrollArea) self.setLayout(layout)
or the short version:
layout = QVBoxLayout(self) # Create a layout and apply it to it's parent layout->addWidget(scrollArea)
-
@SGaist
Thanks for this, when I get back to code I will review in this light.Does that indeed mean that the example I copied from, https://stackoverflow.com/a/28826793/489865, is not right, as @mrjj was suggesting? That posts says, and I (thought I) followed the code:
•on the bottom is parent widget (for example QDialog)
•on top of this is scrollable area (QScrollArea) of fixed sizei.e. scrollarea straight on dialog, you are putting it on layout, he does not do that? I am getting really confused with the layers of widgets/layouts/scrollareas... :(
-
No, the content of the widget is described correctly on that post.
The two points of interest:
- on the bottom is parent widget (for example QDialog)
- on top of this is scrollable area (QScrollArea) of fixed size
You see ? No layouts involved there. The fact that it's passing a parent to the QScrollArea makes it appear within the dialog.
-
@SGaist
Thanks, but I thought I was to do the same as him, yet in mine you're telling me I need aQVBoxLayout
that he does not need.....I started with a dialog with a vboxlayout and some content. My content overflows the dialog vertically. I want to have a vertical scrollbar against the side of the dialog for its content. That's all I want to add to the original code. I'm finding this mega-complex.... :(
-
What the examples shows is how a QScrollArea work not how to make it fit in a widget.
From your description you want your scroll area to fill your widget so that you don't have to resize it, hence you need to put the area in a layout applied to said widget.
-
@SGaist
OK, thanks, I'll have a play.All I need to understand is the hierarchy I need. If I started with
dialog -> vboxlayout1 -> content
I will now need
dialog -> vboxlayout2 -> scrollarea ( -> widget ?) -> vboxlayout1 -> content
Is that right? I'll need a separate vboxlayout from the one I started from, I don't somehow apply the scrollarea to the original vboxlayout? -
To make things clearer:
widget -> vboxlayout1 -> content
<- future content of the QScrollAreadialog -> vboxlayout2 -> scrollarea
<- QScrollArea fitting the "main widget"scrollarea -> widget
<- finally your widget in the QScrollArea -
@SGaist
OK, armed with the understanding of what the actual hierarchy should be, I have now modified to outline:# self == QDialog self.dialogScrollPanel = QVBoxLayout() self.setLayout(self.dialogScrollPanel) scrollArea = QScrollArea(self) scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) scrollArea.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded) scrollArea.setWidgetResizable(True) self.dialogScrollPanel.addWidget(scrollArea) widget = QWidget() scrollArea.setWidget(widget) self.vertLayout = QVBoxLayout() widget.setLayout(self.vertLayout) ...
And sure enough my dialog now looks like:
which is just what I was aiming for!The one bit I'm left hazy on is when you do or do not need to specify an owner/parent for a layout or widget. My code includes:
self.dialogScrollPanel = QVBoxLayout() self.setLayout(self.dialogScrollPanel) widget = QWidget() scrollArea.setWidget(widget) self.vertLayout = QVBoxLayout() widget.setLayout(self.vertLayout)
In each of these cases the constructor could equally be
QVBoxLayout(self)
orQWidget(self)
and I see the same behaviour. In the code I've inherited it seems sometimes it passes an argument to these and sometimes not. When do I need or not need to pass a widget parent/owner argument when creating a widget or layout? -
@JNBarchan
Any widget that is not given a parent will become a window.
So for any widget on a from, you will want to give it a parent.
However, inserting them into other widgets set the parent.For Layouts, its its easier just to assign them to a widget and in that
way give a parent.So in most cases you will just want to give a parent when constructed as
to make sure they are deleted. -
I usually follow these rules:
- When I create layout that should be the "main" layout of a widget, I pass that widget as parent
Note that's just an habit, if you prefer the setLayout method then go for it, just be consistent all over your code base. - All widgets that are put inside a layout will be re-parented appropriately so I don't pass a parent to them.
- Unless I'm going to manipulate the layout later on I don't make it a member of the class
- When I create layout that should be the "main" layout of a widget, I pass that widget as parent