gpt4 book ai didi

python - Pyqt:使用布局管理器在双小部件应用程序上强制执行 sizeHint() 尺寸

转载 作者:太空宇宙 更新时间:2023-11-04 00:29:23 31 4
gpt4 key购买 nike

我有两个小部件彼此相邻,WidgetAWidgetB,在 QDialog 上,带有水平布局管理器。< br/>我正在尝试执行以下尺寸/调整尺寸政策:
对于 WidgetA:

  • 水平方向:宽度应为 900,并且可以收缩(最多 100)和扩展(任意)。
  • 垂直方向:高度应为 600,并且能够扩展(至任何范围)。

对于 WidgetB:

  • 水平方向:宽度应固定为 600。
  • 垂直:高度应为 600,具有扩展能力(可扩展至任何范围)- 与 WidgetA 相同。

但是无论我为WidgetA选择哪种尺寸策略,它仍然不会占用900的宽度。
这是一个代码示例:

class WidgetA(QTextEdit):

def __init__(self, parent = None):
super(WidgetA, self).__init__(parent)
#self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding) --> WidgetA width still smaller than 900
#self.setSizePolicy(QSizePolicy.Ignored, QSizePolicy.MinimumExpanding) --> WidgetA will be set to minimumSizeHint()
#self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding) --> not good for me, since I want WidgetA to be able to shrink up to minimumSizeHint().width()
#self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.MinimumExpanding) --> not good for me for the same reason - I want WidgetA to be able to shrink up to minimumSizeHint().width()

def minimumSizeHint(self):
return QSize(100, 600)

def sizeHint(self):
return QSize(900, 600)


class WidgetB(QTextEdit):

def __init__(self, parent = None):
super(WidgetB, self).__init__(parent)
self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)

def sizeHint(self):
return QSize(600, 600)

class MainForm(QDialog):

def __init__(self, parent = None):
super(MainForm, self).__init__(parent)

label_a = QLabel('A')
widget_a = WidgetA()
label_a.setBuddy(widget_a)

label_b = QLabel('B')
widget_b = WidgetB()
label_b.setBuddy(widget_b)

hbox = QHBoxLayout()

vbox = QVBoxLayout()
vbox.addWidget(label_a)
vbox.addWidget(widget_a)
widget = QWidget()
widget.setLayout(vbox)

hbox.addWidget(widget)

vbox = QVBoxLayout()
vbox.addWidget(label_b)
vbox.addWidget(widget_b)
widget = QWidget()
widget.setLayout(vbox)

hbox.addWidget(widget)

self.setLayout(hbox)



def run_app():
app = QApplication(sys.argv)
form = MainForm()
form.show()
app.exec_()

if __name__ == '__main__':
run_app()

我能得到的最接近的是当我设置时:

self.setSizePolicy(QSizePolicy.Preferred, QSizePolicy.MinimumExpanding)

WidgetA 上。

enter image description here

似乎 WidgetB 正在占用 WidgetA 的 900 宽度(消除 WidgetB 就可以了),但我应该'受窗口宽度限制。
是什么阻止了窗口本身(MainForm)自动水平扩展以考虑WidgetA 的 900 宽度和 WidgetB的固定宽度是600?

最佳答案

根据 Layout Management 上的文章,添加小部件时应用的规则如下:

  1. All the widgets will initially be allocated an amount of space in accordance with their QWidget::sizePolicy() and QWidget::sizeHint().
  2. If any of the widgets have stretch factors set, with a value greater than zero, then they are allocated space in proportion to their stretch factor (explained below).
  3. If any of the widgets have stretch factors set to zero they will only get more space if no other widgets want the space. Of these, space is allocated to widgets with an Expanding size policy first.
  4. Any widgets that are allocated less space than their minimum size (or minimum size hint if no minimum size is specified) are allocated this minimum size they require. (Widgets don't have to have a minimum size or minimum size hint in which case the stretch factor is their determining factor.)
  5. Any widgets that are allocated more space than their maximum size are allocated the maximum size space they require. (Widgets do not have to have a maximum size in which case the stretch factor is their determining factor.)

因此,您最多可以定义 sizeHintminimumSizeHint,设置一个大于所有其他参数的拉伸(stretch)因子,并设置 的大小策略展开。但即使所有这些都到位了,布局管理器似乎仍然不能保证在最小尺寸提示较小时遵守尺寸提示。

问题是 Expanding 的定义还不够强:

The sizeHint() is a sensible size, but the widget can be shrunk and still be useful. The widget can make use of extra space, so it should get as much space as possible (e.g. the horizontal direction of a horizontal slider).

无论出于何种原因,如果另一个小部件具有更强的尺寸策略(例如 Fixed),布局管理器似乎优先于收缩而不是扩展。从您的示例的角度来看,这看起来是错误的选择,但我想在其他情况下它可能更有意义。 Qt4 和 Qt5 中的行为似乎完全相同,所以我不知道它是否应该被视为一个错误,或者只是实现的一个怪癖。

我能想出的最简单的解决方法是像这样强制执行 widget_a 的大小提示:

class MainForm(QDialog):

def __init__(self, parent = None):
...

self.setLayout(hbox)

widget_a.setMinimumSize(widget_a.sizeHint())
self.adjustSize()
widget_a.setMinimumSize(widget_a.minimumSizeHint())

(注意:仅在使用 Openbox 窗口管理器的 Linux 上进行了测试)。

PS:另请参阅这个非常相似的 SO 问题:Resize window to fit content .

关于python - Pyqt:使用布局管理器在双小部件应用程序上强制执行 sizeHint() 尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46361675/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com