在调整大小事件中修改布局
Modifying layout in resize event
PyQt 5.9.2,Python3.6.6,Windows10
我想 hide/show 小部件根据其容器小部件的当前宽度动态变化。如果 space
占整个宽度的 10% 以下按钮 "One" 被隐藏,则按钮 "Two"。当用户使容器变大时,按钮将再次显示:"Two",然后是 "One"。
这是我的实现的一个非常基本的版本,它大部分都可以工作,但有一个大问题。我开始调整大小,按钮 "One" 隐藏,但随后出现了一些约束,容器的大小无法再减小。我必须释放鼠标按钮并再次启动该过程以隐藏按钮 "Two"。
import sys
from PyQt5 import QtWidgets
form, space, widgets = None, None, None
def resize_event(event):
if free_space_width() < 0:
visible_w = [w for w in widgets if w.isVisible()]
if len(visible_w) > 1: # do not hide the last one
for w in visible_w:
w.hide()
if free_space_width(w.width()) >= 0:
break # enough space
else:
invisible_w = [w for w in widgets if not w.isVisible()]
for w in reversed(invisible_w):
if free_space_width(-w.width()) < 0:
break
w.show()
def free_space_width(shift=0):
"Free space should be at least 10% of the bar width"
return space.width() + shift - 0.1 * form.width()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
form = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(form)
layout.setSpacing(0) # for simplicity
form.resize(480, 64)
form.resizeEvent = resize_event
widgets = [QtWidgets.QPushButton("test button %d" % (i + 1), form)
for i in range(3)]
for i in widgets:
layout.addWidget(i)
space = QtWidgets.QWidget(form) # stretchable space
s_policy = space.sizePolicy()
s_policy.setHorizontalStretch(1)
space.setSizePolicy(s_policy)
layout.addWidget(space)
form.show()
sys.exit(app.exec_())
then some constraint comes into place and the container cannot be reduced in size
layout.setSizeConstraint(QtWidgets.QLayout.SetNoConstraint)
我认为你应该像这样在这段代码下实现它。
layout = QtWidgets.QHBoxLayout(form)
layout.setSpacing(0) # for simplicity
layout.setSizeConstraint(QtWidgets.QLayout.SetNoConstraint)
可以将按钮放在容器小部件中并重新实现 minimumSizeHint
方法,这样 Qt 就不会尝试自行计算。
def minimumSizeHint(self):
return QtCore.QSize(150, 30)
更新:我在 custom layout 的 setGeometry
函数中实现了 show/hide 逻辑。
PyQt 5.9.2,Python3.6.6,Windows10
我想 hide/show 小部件根据其容器小部件的当前宽度动态变化。如果 space
占整个宽度的 10% 以下按钮 "One" 被隐藏,则按钮 "Two"。当用户使容器变大时,按钮将再次显示:"Two",然后是 "One"。
这是我的实现的一个非常基本的版本,它大部分都可以工作,但有一个大问题。我开始调整大小,按钮 "One" 隐藏,但随后出现了一些约束,容器的大小无法再减小。我必须释放鼠标按钮并再次启动该过程以隐藏按钮 "Two"。
import sys
from PyQt5 import QtWidgets
form, space, widgets = None, None, None
def resize_event(event):
if free_space_width() < 0:
visible_w = [w for w in widgets if w.isVisible()]
if len(visible_w) > 1: # do not hide the last one
for w in visible_w:
w.hide()
if free_space_width(w.width()) >= 0:
break # enough space
else:
invisible_w = [w for w in widgets if not w.isVisible()]
for w in reversed(invisible_w):
if free_space_width(-w.width()) < 0:
break
w.show()
def free_space_width(shift=0):
"Free space should be at least 10% of the bar width"
return space.width() + shift - 0.1 * form.width()
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
form = QtWidgets.QWidget()
layout = QtWidgets.QHBoxLayout(form)
layout.setSpacing(0) # for simplicity
form.resize(480, 64)
form.resizeEvent = resize_event
widgets = [QtWidgets.QPushButton("test button %d" % (i + 1), form)
for i in range(3)]
for i in widgets:
layout.addWidget(i)
space = QtWidgets.QWidget(form) # stretchable space
s_policy = space.sizePolicy()
s_policy.setHorizontalStretch(1)
space.setSizePolicy(s_policy)
layout.addWidget(space)
form.show()
sys.exit(app.exec_())
then some constraint comes into place and the container cannot be reduced in size
layout.setSizeConstraint(QtWidgets.QLayout.SetNoConstraint)
我认为你应该像这样在这段代码下实现它。
layout = QtWidgets.QHBoxLayout(form)
layout.setSpacing(0) # for simplicity
layout.setSizeConstraint(QtWidgets.QLayout.SetNoConstraint)
可以将按钮放在容器小部件中并重新实现 minimumSizeHint
方法,这样 Qt 就不会尝试自行计算。
def minimumSizeHint(self):
return QtCore.QSize(150, 30)
更新:我在 custom layout 的 setGeometry
函数中实现了 show/hide 逻辑。