a_guest
a_guest

Reputation: 36239

QScrollArea is expanding instead of scrolling

I have a QScrollArea and I'll add some other widgets to it. What I want is that the QScrollArea starts scrolling when the widgets in it extend its size.

But instead the scroll area starts expanding itself.

Here's the code I've used:

import sys
from PyQt4 import QtGui, QtCore

class Widget(QtGui.QWidget):
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.vbox = QtGui.QVBoxLayout()
        self.setLayout(self.vbox)

    def add_button(self):
        tmp = QtGui.QPushButton("...", self)
        self.vbox.addWidget(tmp)

class ScrollArea(QtGui.QScrollArea):
    def __init__(self, parent=None):
        QtGui.QScrollArea.__init__(self, parent)

        self.vbox = QtGui.QVBoxLayout()

        self.w = Widget(self)
        self.setWidget(self.w)    #set the widget to provide scrolling for here
        self.vbox.addWidget(self.w)

        self.plus = QtGui.QPushButton("button", self)
        self.connect(self.plus, QtCore.SIGNAL("clicked()"), self.add_button)
        self.vbox.addWidget(self.plus)

        self.setLayout(self.vbox)

    def add_button(self):
        self.w.add_button()

app = QtGui.QApplication(sys.argv)
main = ScrollArea()
main.show()
sys.exit(app.exec_())

I also tried to set the layout of the child widget self.w in the class ScrollArea instead of in its own class but it had the same effect.

Upvotes: 1

Views: 967

Answers (1)

a_guest
a_guest

Reputation: 36239

As already pointed out by Bakuriu it is important that one doesn't apply its own layout to the QScrollArea but just specifies one widget (denoted with w in the following) via setWidget as the one the scroll area should take care off.

It is important to set the layout of w before you call setWidget and if one wants to add several other children to w (like the QPushButtons in the above problem) it is also important to call setSizeConstraint for w's layout (e.g. setSizeContraint(QLayout.SetMinAndMaxSize), see this for more options). Follow this link for more details on the behaviour of QScrollArea.

The following code is a working example:

import sys
from PyQt4 import QtGui, QtCore

class Widget(QtGui.QWidget):
    """ Here we add more buttons, if the size of the buttons exceeds the size of the widget scrolling starts. """
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self, parent)

        self.vbox = QtGui.QVBoxLayout()
        self.vbox.setSizeConstraint(QtGui.QLayout.SetMinAndMaxSize)
        self.setLayout(self.vbox)

    def add_button(self):
        tmp = QtGui.QPushButton("...", self)
        self.vbox.addWidget(tmp)

class ScrollArea(QtGui.QScrollArea):
    """ This scroll area only handles one widget for which scrolling should be provided. """
    def __init__(self, parent=None):
        QtGui.QScrollArea.__init__(self, parent)

        self.w = Widget()
        self.setWidget(self.w)    #set the widget to provide scrolling for here

    def add_button(self):
        self.w.add_button()

class MainWindow(QtGui.QWidget):
    """ Use this widget to arrange the QScrollArea and the QPushButton. """
    def __init__(self, parent=None):
        QtGui.QWidget.__init__(self)

        self.vbox = QtGui.QVBoxLayout()
        self.scroll = ScrollArea(self)
        self.vbox.addWidget(self.scroll)

        self.plus = QtGui.QPushButton("button", self)
        self.connect(self.plus, QtCore.SIGNAL("clicked()"), self.add_button)
        self.vbox.addWidget(self.plus)

        self.setLayout(self.vbox)

    def add_button(self):
        self.scroll.add_button()

app = QtGui.QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec_())

Upvotes: 1

Related Questions