David David - 2 months ago 15
Python Question

Issue with resizing a scroll area in pyqt

I'm a little new to working with GUIs in python. I'm experimenting with some features in pyqt. I am working with a scroll area. Above the scroll area I wish to place a text label. However, the scroll area, posts over most of the text label. I would like to resize the scroll area so that the label is completely visible. I thought it would be the command:

self.scrollArea.setGeometry()


Or some variation of of:

self.scrollArea.setWidgetResizable(True)


But these didn't work. Does anyone know the proper way to resize the scroll area so that my text is visible? Thanks for any help. My code is below:

import sys
from PyQt4 import QtGui,QtCore

class myGUI(QtGui.QWidget):
def __init__(self):
super(myGUI, self).__init__()
self.horizontalLayout = QtGui.QVBoxLayout(self)

lbl1 = QtGui.QLabel('This will eventually contain a paragraph of useful information', self)
lbl1.move(17, 0)

self.scrollArea = QtGui.QScrollArea(self)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setGeometry(10,10,10,10)
self.scrollAreaWidgetContents = QtGui.QWidget()
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 380, 280))
self.horizontalLayout_2 = QtGui.QHBoxLayout(self.scrollAreaWidgetContents)
self.gridLayout = QtGui.QGridLayout()
self.horizontalLayout_2.addLayout(self.gridLayout)
self.scrollArea.setWidget(self.scrollAreaWidgetContents)

self.btn1 = QtGui.QPushButton("Button 1")
self.btn2 = QtGui.QPushButton("Button 2")
self.btn3 = QtGui.QPushButton("Button 3")

self.horizontalLayout.addWidget(self.scrollArea)
self.horizontalLayout.addWidget(self.btn1)
self.horizontalLayout.addWidget(self.btn2)
self.horizontalLayout.addWidget(self.btn3)

self.connect(self.btn1, QtCore.SIGNAL("clicked()"), self.addButtons)
self.setGeometry(300, 200, 500, 500)
self.setWindowTitle('myGUI')

def addButtons(self):
for i in range(0, 50):
self.r_button = QtGui.QPushButton("Element %s " % i)
self.gridLayout.addWidget(self.r_button)
def run():

app = QtGui.QApplication(sys.argv)
ex = myGUI()
ex.show()
sys.exit(app.exec_())

if __name__ == "__main__":
run()

Answer

The general mistake you're making, is that you are not letting the layouts do the work for you.

To start with, make sure the label is added to the top of the vertical layout:

    lbl1 = QtGui.QLabel('This will eventually contain a paragraph of useful information', self)
    # get rid of the following line
    # lbl1.move(17, 0)
    self.horizontalLayout.addWidget(lbl1)

and possibly also allow the label to wrap, so that the main window is fully resizable:

    lbl1.setWordWrap(True)

You should also get rid of all the setGeometry calls, other than the one for the main window itself. In general, avoid using absolute sizes and positions for widgets; the layout machinery will almost always do the right thing if it's used in the right way.

One final tip: avoid using the old-style syntax for connecting signals, and switch to the new-style syntax (which is more readable and much less error-prone):

    # self.connect(self.btn1, QtCore.SIGNAL("clicked()"), self.addButtons)
    self.btn1.clicked.connect(self.addButtons)