Как добавить прокрутру содержимого в QGroupBox?
Нужно создать окошко, внутри которого будет GroupBox, в который динамично будут добавляться кнопки.
На случай выхода за пределы границ хочу, чтоб появлялся scroll, но он напрочь отказывается воспринимать мои попытки и отобразиться на экране.
На данный момент я уже и не представляю в чем проблема, надеюсь на помощь, заранее спасибо!
# -*- coding: utf-8 -*-
from PyQt5 import QtCore, QtWidgets
import sys
app = QtWidgets.QApplication(sys.argv)
window = QtWidgets.QWidget()
window.setWindowTitle("Scroll")
window.resize(300,700)
mainbox = QtWidgets.QVBoxLayout() # Сюда поместим GroupBox
vbox = QtWidgets.QVBoxLayout() # Для кнопочек
scroll = QtWidgets.QScrollArea() # Скролиться должен GroupBox
group = QtWidgets.QGroupBox("Check Me") # Этот GroupBox
scroll.setWidget(group) # Для этого я передаю его в ScrollArea
for i in range(50): # Накидываем кнопочки
vbox.addWidget(QtWidgets.QPushButton("button {}".format(i)))
group.setLayout(vbox) # Закидываем область с кнопками в группу
mainbox.addWidget(group) # Закидываем группу в главный слой
window.setLayout(mainbox) # Закрепляем главный слой
window.show()
sys.exit(app.exec_())
Ответы (2 шт):
Я для вам привел более функциональный пример и отметил как правильно делать.
from PyQt5 import QtWidgets, QtGui, QtCore
class GroupBox(QtWidgets.QGroupBox):
clicked = QtCore.pyqtSignal(str, object)
def __init__(self, title):
super(GroupBox, self).__init__()
self.title = title
self.setTitle(self.title)
def mousePressEvent(self, event):
child = self.childAt(event.pos())
if not child:
child = self
self.clicked.emit(self.title, child)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.setWindowTitle("Scroll")
self.resize(300,700)
centralWidget = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
centralWidget.setLayout(layout)
self.setCentralWidget(centralWidget)
my_tree = QtWidgets.QTreeWidget()
layout.addWidget(my_tree)
alpha = QtWidgets.QTreeWidgetItem(my_tree, ['Alpha'])
beta = QtWidgets.QTreeWidgetItem(my_tree, ['Beta'])
alpha.addChild(QtWidgets.QTreeWidgetItem(['one']))
alpha.addChild(QtWidgets.QTreeWidgetItem(['two']))
beta.addChild(QtWidgets.QTreeWidgetItem(['first']))
beta.addChild(QtWidgets.QTreeWidgetItem(['second']))
my_tree.expandAll()
alpha.child(0).setSelected(True)
# +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
scroll = QtWidgets.QScrollArea()
layout.addWidget(scroll)
scrollLayout = QtWidgets.QVBoxLayout()
scrollW = QtWidgets.QWidget()
scroll.setWidget(scrollW)
scrollW.setLayout(scrollLayout)
scrollLayout.setAlignment(QtCore.Qt.AlignTop)
scroll.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)
scroll.setWidgetResizable(True)
# +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
for _ in range(5):
fooGroup = GroupBox(f'GroupBox_{_}')
fooGroup.setObjectName(f'fooGroup {_}')
fooGroup.clicked.connect(self.onFooGroupClick)
fooLayout = QtWidgets.QVBoxLayout()
fooGroup.setLayout(fooLayout)
fooItem1 = QtWidgets.QLabel("fooItem1", objectName="fooItem1")
fooItem1.setStyleSheet('background: #44ffff')
fooItem2 = QtWidgets.QLabel("fooItem2", objectName="fooItem2")
fooItem2.setStyleSheet('background: #ffff56;')
fooItem3 = QtWidgets.QLabel("fooItem3", objectName="fooItem3")
fooItem3.setStyleSheet('background: #ff42ff;')
fooLayout.addWidget(fooItem1)
fooLayout.addWidget(fooItem2)
fooLayout.addWidget(fooItem3)
scrollLayout.addWidget(fooGroup) # +++
def onFooGroupClick(self, title, obj):
print(f"Group: {title}; objectName=`{obj.objectName()}`")
if __name__ == '__main__':
app = QtWidgets.QApplication([])
window = MainWindow()
window.show()
app.exec_()
Если после изучения будет что-то не понятно, спросите.
Update
import sys
from PyQt5.Qt import *
class Widget(QWidget):
def __init__(self):
super().__init__()
widget = QWidget()
#Layout of Container Widget
layout = QVBoxLayout(self)
for _ in range(20):
btn = QPushButton("test")
layout.addWidget(btn)
widget.setLayout(layout)
#Scroll Area Properties
scroll = QScrollArea()
scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
scroll.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll.setWidgetResizable(True)
scroll.setWidget(widget)
#Scroll Area Layer add
vLayout = QVBoxLayout(self)
vLayout.addWidget(scroll)
self.setLayout(vLayout)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = Widget()
dialog.show()
app.exec_()
Как сказано в документации
Отметим, что вы должны добавить лейаут виджета до вызова setWidget; если вы добавите его позже, то виджет не будет виден - даже если вызовите show для области прокрутки.
Note that You must add the layout of widget before you call this function; if you add it later, the widget will not be visible - regardless of when you show() the scroll area. In this case, you can also not show() the widget later.
То есть, для появления скрола последовательность команд должна быть такая:
# 1. Установка лейаута для виджета
group.setLayout(vbox) # Закидываем область с кнопками в группу
# 2. Потом уже добавление группы в скрол
scroll.setWidget(group)

