如何为 QAbstractScrollArea 使用 setSizePolicy
How to use setSizePolicy for QAbstractScrollArea
我正在尝试使用 setSizePolicy property of a QWidget. Using this feature with a QWidget or QFrame works as expected. However, using this feature with a QAbstractScrollArea 结果出乎意料。
以下最小工作示例演示了此行为:
排列成两个 Parent
小部件,左边是 QAbstractScrollArea 小部件的布局,右边是一组 QFrame 小部件。每个小部件都分配了一个单独的高度,并且所有小部件在大小策略中指定固定为 sizeHint return 大小,固定为上述高度。
from PyQt5 import QtCore, QtWidgets
import sys
class ASWidget(QtWidgets.QAbstractScrollArea):
def __init__(self, height, parent=None):
super().__init__(parent)
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self._height = height
self.setStyleSheet("background: red;")
def sizeHint(self):
return QtCore.QSize(100, self._height)
class NonASWidget(QtWidgets.QFrame):
def __init__(self, height, parent=None):
super().__init__(parent)
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self._height = height
self.setStyleSheet("background: red;")
def sizeHint(self):
return QtCore.QSize(100, self._height)
class ParentWidget(QtWidgets.QWidget):
def __init__(self, classType, parent=None):
super().__init__(parent)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(1)
sizes = [5, 15, 25, 35, 45, 55, 65]
for i in sizes:
layout.addWidget(classType(i))
class Dialog(QtWidgets.QDialog):
def __init__(self):
super().__init__()
w1 = ParentWidget(ASWidget, self)
w2 = ParentWidget(NonASWidget, self)
w2.move(110, 0)
def main():
app = QtWidgets.QApplication(sys.argv)
dialog = Dialog()
dialog.show()
app.exec_()
if __name__ == "__main__":
main()
上面代码的结果是这个屏幕截图:
如您所见,与右侧的 QFrame 小部件相比,左侧的 QAbstractScrollArea 小部件不使用固定大小策略。
这背后的原因是什么?我如何将 setSizePolicy 功能与 QAbstractScrollArea 小部件一起使用?
当子class小部件时(除了 QWidget 本身),重要的是要记住所有现有的 Qt 子classes 也设置一些默认属性或重新实现方法,包括抽象的。
minimumSizeHint()
是 推荐的 小部件的最小尺寸,布局将(几乎)始终遵守该尺寸。以下段落很重要:
QLayout will never resize a widget to a size smaller than the minimum size hint unless minimumSize() is set or the size policy is set to QSizePolicy::Ignore. If minimumSize() is set, the minimum size hint will be ignored.
最小提示很重要,因为它仅对布局内的小部件有效,并且它也可以用作 [sub]class“默认”而不是使用 minimumSize()
,应该用于实例。
虽然许多小部件 return 无效(如 已忽略 )最小尺寸提示,但其他小部件则没有,因为默认最小尺寸对它们的性质很重要大小设置。 QAbstractButton 的子 class 和 QAbstractScrollArea 的所有子class 都会发生这种情况。
要覆盖此行为(虽然不建议在特定大小下使用),只需覆盖该方法即可。请注意,最好使用 sizeHint()
return minimumSizeHint()
而不是相反,这样 sizeHint()
始终遵守最小提示,但仍可以在其他子中被覆盖classes.
class ASWidget(QtWidgets.QAbstractScrollArea):
def __init__(self, height, parent=None):
super().__init__(parent)
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self._height = height
self.setStyleSheet("background: red;")
def sizeHint(self):
<b>return self.minimumSizeHint()
def minimumSizeHint(self):
return QtCore.QSize(100, self._height)</b>
我正在尝试使用 setSizePolicy property of a QWidget. Using this feature with a QWidget or QFrame works as expected. However, using this feature with a QAbstractScrollArea 结果出乎意料。
以下最小工作示例演示了此行为:
排列成两个 Parent
小部件,左边是 QAbstractScrollArea 小部件的布局,右边是一组 QFrame 小部件。每个小部件都分配了一个单独的高度,并且所有小部件在大小策略中指定固定为 sizeHint return 大小,固定为上述高度。
from PyQt5 import QtCore, QtWidgets
import sys
class ASWidget(QtWidgets.QAbstractScrollArea):
def __init__(self, height, parent=None):
super().__init__(parent)
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self._height = height
self.setStyleSheet("background: red;")
def sizeHint(self):
return QtCore.QSize(100, self._height)
class NonASWidget(QtWidgets.QFrame):
def __init__(self, height, parent=None):
super().__init__(parent)
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self._height = height
self.setStyleSheet("background: red;")
def sizeHint(self):
return QtCore.QSize(100, self._height)
class ParentWidget(QtWidgets.QWidget):
def __init__(self, classType, parent=None):
super().__init__(parent)
layout = QtWidgets.QVBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.setSpacing(1)
sizes = [5, 15, 25, 35, 45, 55, 65]
for i in sizes:
layout.addWidget(classType(i))
class Dialog(QtWidgets.QDialog):
def __init__(self):
super().__init__()
w1 = ParentWidget(ASWidget, self)
w2 = ParentWidget(NonASWidget, self)
w2.move(110, 0)
def main():
app = QtWidgets.QApplication(sys.argv)
dialog = Dialog()
dialog.show()
app.exec_()
if __name__ == "__main__":
main()
上面代码的结果是这个屏幕截图:
如您所见,与右侧的 QFrame 小部件相比,左侧的 QAbstractScrollArea 小部件不使用固定大小策略。
这背后的原因是什么?我如何将 setSizePolicy 功能与 QAbstractScrollArea 小部件一起使用?
当子class小部件时(除了 QWidget 本身),重要的是要记住所有现有的 Qt 子classes 也设置一些默认属性或重新实现方法,包括抽象的。
minimumSizeHint()
是 推荐的 小部件的最小尺寸,布局将(几乎)始终遵守该尺寸。以下段落很重要:
QLayout will never resize a widget to a size smaller than the minimum size hint unless minimumSize() is set or the size policy is set to QSizePolicy::Ignore. If minimumSize() is set, the minimum size hint will be ignored.
最小提示很重要,因为它仅对布局内的小部件有效,并且它也可以用作 [sub]class“默认”而不是使用 minimumSize()
,应该用于实例。
虽然许多小部件 return 无效(如 已忽略 )最小尺寸提示,但其他小部件则没有,因为默认最小尺寸对它们的性质很重要大小设置。 QAbstractButton 的子 class 和 QAbstractScrollArea 的所有子class 都会发生这种情况。
要覆盖此行为(虽然不建议在特定大小下使用),只需覆盖该方法即可。请注意,最好使用 sizeHint()
return minimumSizeHint()
而不是相反,这样 sizeHint()
始终遵守最小提示,但仍可以在其他子中被覆盖classes.
class ASWidget(QtWidgets.QAbstractScrollArea):
def __init__(self, height, parent=None):
super().__init__(parent)
self.setSizePolicy(QtWidgets.QSizePolicy.Fixed, QtWidgets.QSizePolicy.Fixed)
self._height = height
self.setStyleSheet("background: red;")
def sizeHint(self):
<b>return self.minimumSizeHint()
def minimumSizeHint(self):
return QtCore.QSize(100, self._height)</b>