Issue
I have the problem that completely drives me mad.
I am writing GUI application on Python using PyQt5. My application consists of multiple QGroupBoxes, that become visible and non-visible as user switches between them.
One of QGroupBoxes contains QScrollArea, in which another QGroupBoxes are placed. As user adds information to application, new QGroupBoxes might be added, so QScrollArea should allow to view all of them when there are too much elements added.
So the structure of elements is:
QGroupBox
=>QScrollArea
=>=>QScrollAreaWidgetContents
=>=>=>QVBoxLayout
=>=>=>=>QGroupBox
=>=>=>=>=>QFormLayout
=>=>=>=>QGroupBox
=>=>=>=>=>QFormLayout
However, even though I placed inner QGroupBoxes inside a vertical layout and then inside a single QScrollAreaWidgetContents, QScrollArea does not show any scrollbars, but instead resizes inner elements, so it looks like this.
My problem can be summed up in this example:
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(415, 213)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(0, 0, 801, 601))
self.groupBox.setObjectName("groupBox")
self.scrollArea = QtWidgets.QScrollArea(self.groupBox)
self.scrollArea.move(10, 30)
self.scrollArea.setFixedWidth(380)
self.scrollArea.setMinimumHeight(160)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.move(0, 0)
self.scrollAreaWidgetContents.setFixedWidth(378)
self.scrollAreaWidgetContents.setMinimumHeight(158)
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
MainWindow.setCentralWidget(self.centralwidget)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
class competencyBox(QWidget):
def __init__(self, parent):
super(competencyBox, self).__init__(parent)
self.compCodeLineEdit = QLineEdit()
self.compDescrpTextEdit = QTextEdit()
self.box = QGroupBox(self)
self.form_lay = QFormLayout(self)
self.form_lay.addRow(QLabel("Код: "), self.compCodeLineEdit)
self.form_lay.addRow(QLabel("Описание: "), self.compDescrpTextEdit)
self.box.setLayout(self.form_lay)
self.box.setFixedSize(510, 240)
class test_window(QMainWindow):
def __init__(self):
super(test_window, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.addBox(self.ui.scrollAreaWidgetContents, competencyBox, 4)
def addBox(self, parent, element, number):
vert_lay = QVBoxLayout(parent)
for i in range(number):
e = element(parent)
vert_lay.addWidget(e)
vert_lay.setSpacing(5)
As you may notice, I tried different approaches, such as setting fixed size to inner QGroupBoxes, adding spacing into the vertical layout and so on, but QScrollArea still ignores them and shrinks inner elements. I am stuck and got no idea how to solve my problem. Please help me.
Solution
The main problem in your case is that the scrollAreaWidgetContents should not have a fixed size since it is the container of the widgets and if you use self.scrollAreaWidgetContents.setFixedWidth (378) you are setting it, the size of the scrollAreaWidgetContents should be the set size. widgets through the QVBoxLayout.
Another problem is that CompetencyBox must use a layout to set up the QGroupBox.
from PyQt5 import QtCore, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(415, 213)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.groupBox = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox.setGeometry(QtCore.QRect(0, 0, 801, 601))
self.groupBox.setObjectName("groupBox")
self.scrollArea = QtWidgets.QScrollArea(self.groupBox)
self.scrollArea.move(10, 30)
self.scrollArea.setFixedWidth(380)
self.scrollArea.setMinimumHeight(160)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setObjectName("scrollArea")
self.scrollAreaWidgetContents = QtWidgets.QWidget()
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
MainWindow.setCentralWidget(self.centralwidget)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
class CompetencyBox(QtWidgets.QWidget):
def __init__(self, parent=None):
super(CompetencyBox, self).__init__(parent)
self.compCodeLineEdit = QtWidgets.QLineEdit()
self.compDescrpTextEdit = QtWidgets.QTextEdit()
lay = QtWidgets.QVBoxLayout(self)
box = QtWidgets.QGroupBox()
lay.addWidget(box)
form_lay = QtWidgets.QFormLayout()
form_lay.addRow(QtWidgets.QLabel("Код: "), self.compCodeLineEdit)
form_lay.addRow(QtWidgets.QLabel("Описание: "), self.compDescrpTextEdit)
box.setLayout(form_lay)
box.setFixedSize(510, 240)
class Test_Window(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Test_Window, self).__init__(parent)
self.setupUi(self)
self.addBox(self.scrollAreaWidgetContents, CompetencyBox, 4)
def addBox(self, parent, element, number):
vert_lay = QtWidgets.QVBoxLayout(parent)
for i in range(number):
vert_lay.addWidget(element())
vert_lay.setSpacing(5)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = Test_Window()
w.resize(640, 480)
w.show()
sys.exit(app.exec_())
Answered By - eyllanesc
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.