Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create a scrollable QVBoxLayout?

Tags:

qt

pyqt

I'm trying to put a QVBoxLayout inside a QScrollArea in order for it to be scrollable vertically. However items don't seem to be added to it.

I saw a suggestion that I ought to create an inner widget that the ScrollArea uses and to place the layout inside that, although it doesn't seem to have worked. My structure is supposed to look like this:

+------------------------------- | QScrollArea(realmScroll) | +---------------------------- | | QWidget(realmScrollInner) | | +------------------------- | | | QVBoxLayout(realmLayout) 

And the code to do this:

# Irrelevant, added for context (this works) centralWidget = QWidget(self) self.container = QVBoxLayout(centralWidget) centralWidget.setLayout(self.container) self.setCentralWidget(centralWidget)  # Where trouble starts self.realmScroll = QScrollArea(self.container.widget()) self.realmScroll.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)  self.realmLayout = QVBoxLayout(self.container.widget())  self.realmScrollInner = QWidget(self.realmScroll) self.realmScrollInner.setLayout(self.realmLayout)  self.realmScroll.setWidget(self.realmScrollInner) self.container.addWidget(self.realmScroll)  # Doesn't add to realmLayout self.realmLayout.addWidget(QLabel("test")) 

I'm still learning Qt (2 days in), so in-depth answers to where I'm going wrong would be appreciated.

Update:

It seems that the addWidget(QLabel()) works right up until the realmScrollInner has been set as realmScroll's widget. Since I'd like to add elements after the UI has been displayed I have to do this, which I'm not sure is really correct:

self.realmLayout.addWidget(QLabel("test"))  # realmScrollInner bound to realmScroll realmScroll.setWidget(realmScrollInner) self.container.addWidget(realmScroll)  # Access realmScroll's widget and then layout to add realmScroll.widget().layout().addWidget(QLabel("test")) 

But if you remove that first call to addWidget before the widget has been bound (so the layout has no widgets), then bind to the ScrollArea widgets added afterwards are not displayed. Perhaps the ScrollArea needs repainting (although I don't see a method for that)?

Update 2: Calling repaint() on realmScroll or its contained widget does nothing, as does calling activate/update() on the layout.

like image 693
Ross Avatar asked Jul 03 '11 22:07

Ross


People also ask

How do you use QScrollArea?

You do not have to add a layout to QScrollArea, what you must pass is a widget, so that layout that you have built must be added to a widget, and that widget must be set to QScrollArea. Every time you call createLayout_group you are overwriting the member of the class self.


1 Answers

It turned out that I was lead down a wrong path by putting the layout as the layout of a widget. The actual way to do this is as simple as:

scrollarea = QScrollArea(parent.widget()) layout = QVBoxLayout(scrollarea) realmScroll.setWidget(layout.widget())  layout.addWidget(QLabel("Test")) 

Which I'm pretty sure I tried originally, but hey it's working.

However this adds an issue that the layout's items are shrunk vertically instead of causing the scrollarea to add a scrollbar.

like image 65
Ross Avatar answered Nov 09 '22 01:11

Ross