PySide6 中如何按 QFrame 高度设置百分比内边距?
数据阿明
结论
Qt 样式表中的 padding: 10% 无法可靠地按外层 QFrame 高度的 10% 设置内边距。可以在外层 QFrame 的 resizeEvent() 中读取当前高度,换算成像素,再通过布局的 setContentsMargins() 更新四边边距。
为什么 margin: 0 没有改变布局边距
样式表中的 margin 是控件的样式属性,QVBoxLayout.setContentsMargins() 设置的则是布局内容区域与布局边缘之间的空间。它们作用于不同层面,因此子控件样式表里的 margin: 0 不会自动改变布局的内容边距。
原代码将外层布局的边距设为零:
outerLayout.setContentsMargins(0, 0, 0, 0)
这样布局的四周就不会预留空间。若要根据外层框的高度设置留白,应更新这个布局的边距。
按高度比例设置边距
下面的示例将四边边距设为外层 QFrame 当前高度的 10%。窗口或外层框大小改变时,代码会重新计算边距:
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QFrame
class PaddedFrame(QFrame):
def __init__(self, parent=None):
super().__init__(parent)
self._layout = QVBoxLayout(self)
self._layout.setContentsMargins(0, 0, 0, 0)
def resizeEvent(self, event):
super().resizeEvent(event)
padding = round(self.height() * 0.10)
self._layout.setContentsMargins(padding, padding, padding, padding)
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
outer_frame = PaddedFrame()
outer_frame.setStyleSheet("QFrame { background-color: green; }")
inner_frame = QFrame()
inner_frame.setStyleSheet(
"QFrame { background-color: red; border: 1px inset black; }"
)
outer_frame.layout().addWidget(inner_frame)
self.setCentralWidget(outer_frame)
app = QApplication([])
window = MainWindow()
window.show()
app.exec()
round(self.height() * 0.10) 会将高度换算为整数像素,再传给 setContentsMargins(left, top, right, bottom)。若只需上下留白,可以将计算结果用于第二和第四个参数。若希望水平间距随宽度变化,则应根据宽度单独计算左右边距。
注意事项
这种写法通过布局边距模拟外层框的内边距。边距会占用子控件的可用空间,也可能影响布局的最小尺寸。内容尺寸较大时,可能需要结合布局约束调整窗口的实际高度和预期比例。
备注:内容仅供参考。
