QSizePolicy.Minimum 和 QSizePolicy.Preferred 有什么区别?
What's the difference between QSizePolicy.Minimum and QSizePolicy.Preferred?
我读到“首选策略是非常灵活的策略,小部件的大小可以比 sizeHint() 更小和更大。”
但是当我增加或减少 windows 的大小时,我找不到它们之间的任何差异。
from PySide2 import QtWidgets
app = QtWidgets.QApplication([])
window = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
vMinimumButton = QtWidgets.QPushButton("h_Minimum, v_Fixed")
hMinimumButton = QtWidgets.QPushButton("h_Fixed, v_Minimum")
bMinimumButton = QtWidgets.QPushButton("h_Minimum, v_Minimum")
vMinimumButton.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
hMinimumButton.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
bMinimumButton.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
layout.addWidget(vMinimumButton)
layout.addWidget(hMinimumButton)
layout.addWidget(bMinimumButton)
window.setLayout(layout)
window.show()
app.exec_()
from PySide2 import QtWidgets
app = QtWidgets.QApplication([])
window = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
vPreferredButton = QtWidgets.QPushButton("h_Preferred, v_Fixed")
hPreferredButton = QtWidgets.QPushButton("h_Fixed, v_Preferred")
bPreferredButton = QtWidgets.QPushButton("h_Preferred, v_Preferred")
vPreferredButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
hPreferredButton.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
bPreferredButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
layout.addWidget(vPreferredButton)
layout.addWidget(hPreferredButton)
layout.addWidget(bPreferredButton)
window.setLayout(layout)
window.show()
app.exec_()
Qt 文档的 policy section 中对此进行了介绍。
“首选”策略允许根据提示大小缩小和增大控件。 “最低”政策只允许增长。
后者永远不会让您缩小到提示的尺寸以下。
这些策略是策略标志的不同组合,详细here:
QSizePolicy::GrowFlag = 1
: 如有必要,小部件可以超出其大小提示。
QSizePolicy::ExpandFlag = 2
:小部件应尽可能多地获得 space。
QSizePolicy::ShrinkFlag = 4
: 如有必要,小部件可以缩小到其大小提示以下。
QSizePolicy::IgnoreFlag = 8
:忽略小部件的大小提示。小部件将获得尽可能多的 space。
除了简洁但完整的 。
,我想补充一些见解
首先,乍一看,Qt 大小策略名称是违反直觉的。
理解它们需要对文档进行仔细和耐心的理解,可能还需要进行一些测试。一旦你明白了它的要点,你可能会意识到命名背后的逻辑和假设,它实际上是有道理的(不直观并不总是意味着错误:复杂的主题需要更多的意识,以避免仅根据直觉做出错误的选择。
需要了解的重要一点是,它们总是参考小部件的 大小提示 ,并且指示如何将该提示用作参考。
Maximum
表示提示将用作小部件的 最大 大小:它不能大于该大小。
Minimum
表示提示是最小大小,所以不能再小了。
请记住,minimum*
和 maximum*
(*
为 Size
、Width
或 Height
)会覆盖这些方面。
Expanding
表示提示是首选大小,如果还剩下一些 space,该小部件将尝试使用它。
然后我们必须考虑到 QWidget 也有一个 minimumSizeHint
,这是推荐的最小尺寸:如果它 returns 是一个有效尺寸,它可以 而不是 更小(同样,除非明确给出最小尺寸)。
我们还必须意识到某些小部件具有特殊的行为,这也解释了为什么您在代码中看不到差异:例如 QPushButton,returns sizeHint()
即使 minimumSizeHint()
,以其内容为准,仅对其宽度有效;默认情况下,Qt 按钮具有固定高度。
一如既往,试验是理解行为的完美方式。
以下是一个基本示例,可以更好地说明政策的运作方式;使用基本的 QWidget 作为基础可以避免由特定于小部件的提示和策略引起的意外行为。
您可以使用上下文菜单设置策略,然后最终调整 window 的大小以查看结果。显示的值显示当前策略和大小提示。
from PySide2 import QtCore, QtGui, QtWidgets
policyNames = 'Fixed', 'Minimum', 'Maximum', 'Preferred', 'Expanding'
policyNameDict = {}
policyValueDict = {}
for name in policyNames:
policy = getattr(QtWidgets.QSizePolicy, name)
policyNameDict[policy] = name
policyValueDict[name] = policy
class TestWidget(QtWidgets.QWidget):
def sizeHint(self):
return QtCore.QSize(150, 30)
def minimumSizeHint(self):
return QtCore.QSize(10, 10)
def contextMenuEvent(self, event):
currentPolicy = self.sizePolicy()
menu = QtWidgets.QMenu()
group = QtWidgets.QActionGroup(menu, exclusive=True)
for name in policyNames:
action = group.addAction(name)
action.setCheckable(True)
policy = policyValueDict[name]
action.setData(policy)
if policy == currentPolicy.horizontalPolicy():
action.setChecked(True)
menu.addActions(group.actions())
res = menu.exec_(event.globalPos())
if res:
# PySide requires reconversion of the data, on PyQt the
# res.data() alone is enough;
currentPolicy.setHorizontalPolicy(
QtWidgets.QSizePolicy.Policy(res.data()))
self.setSizePolicy(currentPolicy)
self.update()
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.drawRect(self.rect().adjusted(0, 0, -1, -1))
text = '{policy}\n{width}x{height}'.format(
policy=policyNameDict[self.sizePolicy().horizontalPolicy()],
width=self.sizeHint().width(),
height=self.sizeHint().height(),
)
qp.drawText(self.rect(), QtCore.Qt.AlignCenter, text)
app = QtWidgets.QApplication([])
window = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(window)
for i in range(3):
layout.addWidget(TestWidget())
window.show()
app.exec_()
我读到“首选策略是非常灵活的策略,小部件的大小可以比 sizeHint() 更小和更大。”
但是当我增加或减少 windows 的大小时,我找不到它们之间的任何差异。
from PySide2 import QtWidgets
app = QtWidgets.QApplication([])
window = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
vMinimumButton = QtWidgets.QPushButton("h_Minimum, v_Fixed")
hMinimumButton = QtWidgets.QPushButton("h_Fixed, v_Minimum")
bMinimumButton = QtWidgets.QPushButton("h_Minimum, v_Minimum")
vMinimumButton.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
hMinimumButton.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Minimum)
bMinimumButton.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Minimum)
layout.addWidget(vMinimumButton)
layout.addWidget(hMinimumButton)
layout.addWidget(bMinimumButton)
window.setLayout(layout)
window.show()
app.exec_()
from PySide2 import QtWidgets
app = QtWidgets.QApplication([])
window = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
vPreferredButton = QtWidgets.QPushButton("h_Preferred, v_Fixed")
hPreferredButton = QtWidgets.QPushButton("h_Fixed, v_Preferred")
bPreferredButton = QtWidgets.QPushButton("h_Preferred, v_Preferred")
vPreferredButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Fixed)
hPreferredButton.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Preferred)
bPreferredButton.setSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Preferred)
layout.addWidget(vPreferredButton)
layout.addWidget(hPreferredButton)
layout.addWidget(bPreferredButton)
window.setLayout(layout)
window.show()
app.exec_()
Qt 文档的 policy section 中对此进行了介绍。
“首选”策略允许根据提示大小缩小和增大控件。 “最低”政策只允许增长。
后者永远不会让您缩小到提示的尺寸以下。
这些策略是策略标志的不同组合,详细here:
QSizePolicy::GrowFlag = 1
: 如有必要,小部件可以超出其大小提示。QSizePolicy::ExpandFlag = 2
:小部件应尽可能多地获得 space。QSizePolicy::ShrinkFlag = 4
: 如有必要,小部件可以缩小到其大小提示以下。QSizePolicy::IgnoreFlag = 8
:忽略小部件的大小提示。小部件将获得尽可能多的 space。
除了简洁但完整的
首先,乍一看,Qt 大小策略名称是违反直觉的。
理解它们需要对文档进行仔细和耐心的理解,可能还需要进行一些测试。一旦你明白了它的要点,你可能会意识到命名背后的逻辑和假设,它实际上是有道理的(不直观并不总是意味着错误:复杂的主题需要更多的意识,以避免仅根据直觉做出错误的选择。
需要了解的重要一点是,它们总是参考小部件的 大小提示 ,并且指示如何将该提示用作参考。
Maximum
表示提示将用作小部件的 最大 大小:它不能大于该大小。
Minimum
表示提示是最小大小,所以不能再小了。
请记住,minimum*
和 maximum*
(*
为 Size
、Width
或 Height
)会覆盖这些方面。
Expanding
表示提示是首选大小,如果还剩下一些 space,该小部件将尝试使用它。
然后我们必须考虑到 QWidget 也有一个 minimumSizeHint
,这是推荐的最小尺寸:如果它 returns 是一个有效尺寸,它可以 而不是 更小(同样,除非明确给出最小尺寸)。
我们还必须意识到某些小部件具有特殊的行为,这也解释了为什么您在代码中看不到差异:例如 QPushButton,returns sizeHint()
即使 minimumSizeHint()
,以其内容为准,仅对其宽度有效;默认情况下,Qt 按钮具有固定高度。
一如既往,试验是理解行为的完美方式。
以下是一个基本示例,可以更好地说明政策的运作方式;使用基本的 QWidget 作为基础可以避免由特定于小部件的提示和策略引起的意外行为。
您可以使用上下文菜单设置策略,然后最终调整 window 的大小以查看结果。显示的值显示当前策略和大小提示。
from PySide2 import QtCore, QtGui, QtWidgets
policyNames = 'Fixed', 'Minimum', 'Maximum', 'Preferred', 'Expanding'
policyNameDict = {}
policyValueDict = {}
for name in policyNames:
policy = getattr(QtWidgets.QSizePolicy, name)
policyNameDict[policy] = name
policyValueDict[name] = policy
class TestWidget(QtWidgets.QWidget):
def sizeHint(self):
return QtCore.QSize(150, 30)
def minimumSizeHint(self):
return QtCore.QSize(10, 10)
def contextMenuEvent(self, event):
currentPolicy = self.sizePolicy()
menu = QtWidgets.QMenu()
group = QtWidgets.QActionGroup(menu, exclusive=True)
for name in policyNames:
action = group.addAction(name)
action.setCheckable(True)
policy = policyValueDict[name]
action.setData(policy)
if policy == currentPolicy.horizontalPolicy():
action.setChecked(True)
menu.addActions(group.actions())
res = menu.exec_(event.globalPos())
if res:
# PySide requires reconversion of the data, on PyQt the
# res.data() alone is enough;
currentPolicy.setHorizontalPolicy(
QtWidgets.QSizePolicy.Policy(res.data()))
self.setSizePolicy(currentPolicy)
self.update()
def paintEvent(self, event):
qp = QtGui.QPainter(self)
qp.drawRect(self.rect().adjusted(0, 0, -1, -1))
text = '{policy}\n{width}x{height}'.format(
policy=policyNameDict[self.sizePolicy().horizontalPolicy()],
width=self.sizeHint().width(),
height=self.sizeHint().height(),
)
qp.drawText(self.rect(), QtCore.Qt.AlignCenter, text)
app = QtWidgets.QApplication([])
window = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(window)
for i in range(3):
layout.addWidget(TestWidget())
window.show()
app.exec_()