伙计们。
寻求您的帮助来对我的测试脚本进行故障排除。 我正在练习制作带有小部件的可折叠按钮。
脚本主要来自another question中有关可折叠按钮的stackoverflow。
因此,我试图将QTabWidget
放在class CollpsibleBox(QWidget)
下。问题是我的CollapsibleBox动作很怪异-按钮在跳动,有时无法正确打开/关闭。
我想知道将我的小部件正确放置在QTabWidget
下是否有些错误,或者动画是否存在某些问题?
import random
from PySide2.QtGui import QPixmap, QBrush, QColor, QIcon, QPainterPath, QPolygonF, QPen, QTransform
from PySide2.QtCore import QSize, Qt, Signal, QPointF, QRect, QPoint, QParallelAnimationGroup, QPropertyAnimation, QAbstractAnimation
from PySide2.QtWidgets import QMainWindow, QDialog, QVBoxLayout, QHBoxLayout, QGraphicsView, QGraphicsScene, QFrame, \
QSizePolicy, QGraphicsPixmapItem, QApplication, QRubberBand, QMenu, QMenuBar, QTabWidget, QWidget, QPushButton, \
QSlider, QGraphicsPolygonItem, QToolButton, QScrollArea, QLabel
extraDict = {'buttonSetA': ['test'], 'buttonSetB': ['test']}
tabList = ['Main', 'Extra']
_ui = dict()
class MainWindow(QDialog):
def __init__(self, parent=None):
QDialog.__init__(self, parent=parent)
self.create()
def create(self, **kwargs):
_ui['mainLayout'] = QVBoxLayout()
_ui['tabWidget'] = QTabWidget()
_ui['mainLayout'].addWidget(_ui['tabWidget'])
for tab in tabList:
_ui['tab' + tab] = QWidget()
_ui['tabWidget'].addTab(_ui['tab' + tab], tab)
_ui['tabExtra'].layout = QVBoxLayout()
_ui['tabExtra'].setLayout(_ui['tabExtra'].layout)
_ui['content'] = QWidget()
_ui['tabExtra'].layout.addWidget(_ui['content'])
vlay = QVBoxLayout(_ui['content'])
for name in extraDict.keys():
box = CollapsibleBox(name)
vlay.addWidget(box)
lay = QVBoxLayout()
for j in range(8):
label = QLabel("{}".format(j))
color = QColor(*[random.randint(0, 255) for _ in range(3)])
label.setStyleSheet(
"background-color: {}; color : white;".format(color.name())
)
label.setAlignment(Qt.AlignCenter)
lay.addWidget(label)
box.setContentLayout(lay)
self.setLayout(_ui['mainLayout'])
class CollapsibleBox(QWidget):
def __init__(self, name):
super(CollapsibleBox, self).__init__()
self.toggle_button = QToolButton(text=name, checkable=True, checked=False)
self.toggle_button.setToolButtonStyle(Qt.ToolButtonTextBesideIcon)
self.toggle_button.setArrowType(Qt.RightArrow)
self.toggle_button.pressed.connect(self.on_pressed)
self.toggle_animation = QParallelAnimationGroup(self)
self.content_area = QScrollArea(maximumHeight=0, minimumHeight=0)
self.content_area.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Fixed)
self.content_area.setFrameShape(QFrame.NoFrame)
lay = 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(QPropertyAnimation(self, b"minimumHeight"))
self.toggle_animation.addAnimation(QPropertyAnimation(self, b"maximumHeight"))
self.toggle_animation.addAnimation(QPropertyAnimation(self.content_area, b"maximumHeight"))
def on_pressed(self):
checked = self.toggle_button.isChecked()
self.toggle_button.setArrowType(Qt.DownArrow if not checked else Qt.RightArrow)
self.toggle_animation.setDirection(QAbstractAnimation.Forward
if not checked
else 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)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
window = MainWindow()
window.setGeometry(500, 100, 500, 500)
window.show()
sys.exit(app.exec_())
答案 0 :(得分:2)
问题在于,您只向整个布局添加了两个小部件,并且布局将尝试将它们尽可能地放置好(通常根据其大小提示,将其放置在每个小部件可用区域的中心) )。
您可以设置布局的小部件的对齐方式(将按钮放在其可用空间的顶部):
vlay = QVBoxLayout(_ui['content'])
for name in extraDict.keys():
box = CollapsibleBox(name)
vlay.addWidget(box, alignment=Qt.AlignTop)
或在布局的底部添加一个拉伸:
vlay = QVBoxLayout(_ui['content'])
for name in extraDict.keys():
# ...
vlay.addStretch(1)
将所有按钮置于布局顶部。
作为旁注,我建议您避免使用ui的字典逻辑,因为它可能会变得非常混乱并且容易出错。如果您确实出于某些原因(我希望非常很好)这样做,可以,但是在提问时请避免使用它:这使得真的很难阅读您的代码,而人们最终可能会完全忽略了您的问题。