Как обновить всю компоновку в шаблоне после изменения одного QWidget?
У меня есть вот такой код который при нажатии кнопки "click_me" показывает или скрывает виджет "mini_window"
from PySide2.QtCore import (QCoreApplication, QMetaObject, QObject, QPoint,
QRect, QSize, QUrl, Qt)
from PySide2.QtGui import (QBrush, QColor, QConicalGradient, QCursor, QFont,
QFontDatabase, QIcon, QLinearGradient, QPalette, QPainter, QPixmap,
QRadialGradient)
from PySide2.QtWidgets import *
from PySide2.QtCore import QPropertyAnimation, QRect,QTimer
from PySide2.QtWidgets import QApplication,QWidget
import sys
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
if MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(800, 600)
MainWindow.setStyleSheet(u"#centralwidget QWidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget{\n"
"background:#000;\n"
"color:#fff;\n"
"}\n"
"\n"
"\n"
"#centralwidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget QWidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget,\n"
"#centralwidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget QWidget{\n"
"background:#fff;\n"
"color:#000;\n"
"}\n"
"\n"
"")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.widget = QWidget(self.centralwidget)
self.widget.setObjectName(u"widget")
self.widget.setGeometry(QRect(120, 30, 191, 461))
self.verticalLayout_4 = QVBoxLayout(self.widget)
self.verticalLayout_4.setObjectName(u"verticalLayout_4")
self.main_winow = QWidget(self.widget)
self.main_winow.setObjectName(u"main_winow")
self.verticalLayout = QVBoxLayout(self.main_winow)
self.verticalLayout.setObjectName(u"verticalLayout")
self.click_me = QPushButton(self.main_winow)
self.click_me.setObjectName(u"click_me")
self.verticalLayout.addWidget(self.click_me)
self.mini_window = QWidget(self.main_winow)
self.mini_window.setObjectName(u"mini_window")
self.gridLayout = QGridLayout(self.mini_window)
self.gridLayout.setObjectName(u"gridLayout")
self.text_label = QLabel(self.mini_window)
self.text_label.setObjectName(u"text_label")
self.gridLayout.addWidget(self.text_label, 0, 0, 1, 1)
self.verticalLayout.addWidget(self.mini_window)
self.verticalLayout_4.addWidget(self.main_winow)
self.widget_4 = QWidget(self.widget)
self.widget_4.setObjectName(u"widget_4")
self.verticalLayout_2 = QVBoxLayout(self.widget_4)
self.verticalLayout_2.setObjectName(u"verticalLayout_2")
self.pushButton_2 = QPushButton(self.widget_4)
self.pushButton_2.setObjectName(u"pushButton_2")
self.verticalLayout_2.addWidget(self.pushButton_2)
self.widget_5 = QWidget(self.widget_4)
self.widget_5.setObjectName(u"widget_5")
self.gridLayout_2 = QGridLayout(self.widget_5)
self.gridLayout_2.setObjectName(u"gridLayout_2")
self.label_2 = QLabel(self.widget_5)
self.label_2.setObjectName(u"label_2")
self.gridLayout_2.addWidget(self.label_2, 0, 0, 1, 1)
self.verticalLayout_2.addWidget(self.widget_5)
self.verticalLayout_4.addWidget(self.widget_4)
self.widget_6 = QWidget(self.widget)
self.widget_6.setObjectName(u"widget_6")
self.verticalLayout_3 = QVBoxLayout(self.widget_6)
self.verticalLayout_3.setObjectName(u"verticalLayout_3")
self.pushButton_3 = QPushButton(self.widget_6)
self.pushButton_3.setObjectName(u"pushButton_3")
self.verticalLayout_3.addWidget(self.pushButton_3)
self.widget_7 = QWidget(self.widget_6)
self.widget_7.setObjectName(u"widget_7")
self.gridLayout_3 = QGridLayout(self.widget_7)
self.gridLayout_3.setObjectName(u"gridLayout_3")
self.label_3 = QLabel(self.widget_7)
self.label_3.setObjectName(u"label_3")
self.gridLayout_3.addWidget(self.label_3, 0, 0, 1, 1)
self.verticalLayout_3.addWidget(self.widget_7)
self.verticalLayout_4.addWidget(self.widget_6)
self.verticalSpacer = QSpacerItem(20, 188, QSizePolicy.Minimum, QSizePolicy.Expanding)
self.verticalLayout_4.addItem(self.verticalSpacer)
self.verticalLayout_4.setStretch(3, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0, 0, 800, 21))
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow", u"MainWindow", None))
self.click_me.setText(QCoreApplication.translate("MainWindow", u"click_me", None))
self.text_label.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None))
self.pushButton_2.setText(QCoreApplication.translate("MainWindow", u"test", None))
self.label_2.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None))
self.pushButton_3.setText(QCoreApplication.translate("MainWindow", u"test", None))
self.label_3.setText(QCoreApplication.translate("MainWindow", u"TextLabel", None))
# retranslateUi
class QtMainWindow(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUi(self)
self.click_me.setText('Скрыть `mini_window`') # +++
self.click_me.clicked.connect(self.doAnimation) # +++
QTimer.singleShot(10, self.size_mini_window) # +++
def size_mini_window(self): # +++
self.s = self.mini_window.size()
def doAnimation(self): # +++
if self.click_me.text() == 'Скрыть `mini_window`':
self.anim = QPropertyAnimation(self.mini_window, b"size")
self.anim.setDuration(1500)
self.anim.setStartValue(self.s)
self.anim.setEndValue(QSize(self.s.width(), 0))
self.anim.start()
self.click_me.setText('Показать `mini_window`')
else:
self.anim = QPropertyAnimation(self.mini_window, b"size")
self.anim.setDuration(1500)
self.anim.setStartValue(QSize(self.s.width(), 0))
self.anim.setEndValue(self.s)
self.anim.start()
self.click_me.setText('Скрыть `mini_window`')
if __name__ == '__main__':
my = QApplication(sys.argv)
window = QtMainWindow()
window.show()
sys.exit(my.exec_())
Но проблема в том что компановка окружающих виджетов не изменилась
Мне нужно что бы при нажатии кнопки внешнии виджеты тоже обновлялись
Но как вы видете в моем коде такого не происходит
Как решить данную проблему?
Ответы (1 шт):
Автор решения: S. Nick
→ Ссылка
Я никогда НЕ изменяю код, сгенерированный Qt Designer'ом
и мне не захотелось разбираться с этим кодом.
Я увидел вашу задачу так, попробуйте.
Вам надо только поменять импорты и @QtCore.Slot(), т.к. у меня PyQt5.
import sys
import random
#from PySide2 import QtCore, QtGui, QtWidgets # <--- PySide2
from PyQt5 import QtCore, QtGui, QtWidgets
class CollapsibleBox(QtWidgets.QWidget):
def __init__(self, title="", parent=None):
super(CollapsibleBox, self).__init__(parent)
self.toggle_button = QtWidgets.QToolButton(
text=title, checkable=True, checked=False
)
self.toggle_button.setStyleSheet("QToolButton { border: none; }")
self.toggle_button.setToolButtonStyle(
QtCore.Qt.ToolButtonTextBesideIcon
)
self.toggle_button.setArrowType(QtCore.Qt.RightArrow)
self.toggle_button.pressed.connect(self.on_pressed)
self.toggle_animation = QtCore.QParallelAnimationGroup(self)
self.content_area = QtWidgets.QScrollArea(
maximumHeight=0, minimumHeight=0
)
self.content_area.setSizePolicy(
QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed
)
self.content_area.setFrameShape(QtWidgets.QFrame.NoFrame)
lay = QtWidgets.QVBoxLayout(self)
lay.setSpacing(0)
lay.setContentsMargins(0, 0, 0, 0)
lay.addWidget(self.toggle_button)
lay.addWidget(self.content_area)
self.toggle_animation.addAnimation(
QtCore.QPropertyAnimation(self, b"minimumHeight")
)
self.toggle_animation.addAnimation(
QtCore.QPropertyAnimation(self, b"maximumHeight")
)
self.toggle_animation.addAnimation(
QtCore.QPropertyAnimation(self.content_area, b"maximumHeight")
)
# @QtCore.Slot() # <--- PySide2
@QtCore.pyqtSlot()
def on_pressed(self):
checked = self.toggle_button.isChecked()
self.toggle_button.setArrowType(
QtCore.Qt.DownArrow if not checked else QtCore.Qt.RightArrow
)
self.toggle_animation.setDirection(
QtCore.QAbstractAnimation.Forward
if not checked
else QtCore.QAbstractAnimation.Backward
)
self.toggle_animation.start()
def setContentLayout(self, layout):
lay = self.content_area.layout()
del lay
self.content_area.setLayout(layout)
collapsed_height = (
self.sizeHint().height() - self.content_area.maximumHeight()
)
content_height = layout.sizeHint().height()
for i in range(self.toggle_animation.animationCount()):
animation = self.toggle_animation.animationAt(i)
animation.setDuration(500)
animation.setStartValue(collapsed_height)
animation.setEndValue(collapsed_height + content_height)
content_animation = self.toggle_animation.animationAt(
self.toggle_animation.animationCount() - 1
)
content_animation.setDuration(500)
content_animation.setStartValue(0)
content_animation.setEndValue(content_height)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
centralWidget = QtWidgets.QWidget()
self.setCentralWidget(centralWidget)
vlay = QtWidgets.QVBoxLayout(centralWidget)
for i in range(3):
box = CollapsibleBox("Collapsible Box Header-{}".format(i))
vlay.addWidget(box)
lay = QtWidgets.QVBoxLayout()
lay.setSpacing(0)
lay.setContentsMargins(0, 0, 0, 0)
for j in range(3):
label = QtWidgets.QLabel("Label {}-{}".format(i, j))
color = QtGui.QColor(*[random.randint(0, 255) for _ in range(3)])
label.setStyleSheet(
"background-color: {}; color : white;".format(color.name())
)
label.setAlignment(QtCore.Qt.AlignCenter)
label.setMaximumWidth(150)
label.setMinimumHeight(25)
textButton = "Button {}-{}".format(i, j)
pushButton = QtWidgets.QPushButton(textButton,
clicked=lambda _, t=textButton: print(t))
pushButton.setMaximumWidth(150)
pushButton.setMinimumHeight(25)
lay.addWidget(pushButton)
lay.addWidget(label)
box.setContentLayout(lay)
vlay.addStretch()
if __name__ == "__main__":
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.resize(640, 570)
w.show()
sys.exit(app.exec_())


