【发布时间】:2012-06-01 06:19:30
【问题描述】:
我有一个自定义的QTextEdit 小部件,它在角落有自己的调整大小手柄。我可以很好地调整文本小部件的大小,但是它内部的布局不会随着文本编辑的大小而改变。
有没有办法告诉管理布局根据其中一个小部件中大小的独立变化重新计算自己?
【问题讨论】:
标签: qt
我有一个自定义的QTextEdit 小部件,它在角落有自己的调整大小手柄。我可以很好地调整文本小部件的大小,但是它内部的布局不会随着文本编辑的大小而改变。
有没有办法告诉管理布局根据其中一个小部件中大小的独立变化重新计算自己?
【问题讨论】:
标签: qt
布局尊重其子级的sizeHint() 和minimalSizeHint()(而不是它们的size())。所以你应该重新实现这两个虚拟方法并返回你想要强制的大小。每当您的尺寸提示发生变化时,您应该在自己的小部件上调用 updateGeometry() 以触发小部件所在布局的更新。
查看文档:
virtual QSize QWidget::sizeHint() const此属性保存小部件的推荐大小。
[...]
virtual QSize QWidget::minimumSizeHint() const此属性保存小部件的建议最小尺寸。
[...]
除非设置了 minimumSize() 或将大小策略设置为 QSizePolicy::Ignore,否则 QLayout 永远不会将小部件的大小调整为小于最小大小提示的大小。如果设置了 minimumSize(),则忽略最小尺寸提示。
因此,要强制设置小部件的最小尺寸,请通过返回最小尺寸来实现 minimumSizeHint();要强制固定大小,请通过返回相同大小来实现两者。
我还建议阅读文档页面"Layout Management" 中的以下部分:
布局中的自定义小部件
当您创建自己的小部件类时,您还应该传达其布局属性。如果小部件具有 Qt 的布局之一,这已经被处理了。如果小部件没有任何子小部件,或使用手动布局,您可以使用以下任一或所有机制更改小部件的行为:
- 重新实现 QWidget::sizeHint() 以返回小部件的首选大小。
- 重新实现 QWidget::minimumSizeHint() 以返回小部件可以具有的最小尺寸。
- 调用 QWidget::setSizePolicy() 来指定小部件的空间要求。
每当尺寸提示、最小尺寸提示或尺寸政策发生变化时,调用 QWidget::updateGeometry()。这将导致重新计算布局。多次连续调用 QWidget::updateGeometry() 只会导致一次布局重新计算。
更新(见 cmets):
您还可以通过调用来强制设置尺寸(或仅高度/宽度):
QWidget::setFixedSize(QSize);
QWidget::setFixedHeight(int);
QWidget::setFixedWidth(int);
这些方法只是将大小提示设置为给定值并调用updateGeometry()AFAIK。但也许他们做得更多,因为(如在 cmets 中所见)这是我能找到解决问题的唯一方法。
【讨论】:
updateGeometry()?您使用的是什么布局类型?您是否仔细检查了将小部件添加到布局中的任何错误?在不使用调整大小的手柄的情况下,您的 QTextEdit 是否像往常一样处理布局更改(调整父小部件的大小)?
setFixedHeight 而不是尺寸提示来完成这项工作。在这种情况下,您不需要 updateGeometry。删除尺寸提示内容并将setGeometry( x(), y(), width(), height()-h_diff ); + size_hint_ = QSize( width(), height()-h_diff ); 两行替换为简单的调用setFixedHeight(height()-h_diff);。另一个问题出现了:如果缩小文本区域,外部小部件(在本例中为窗口)也不会缩小。你应该把整个东西放在一个尽可能小的小部件中。我希望我能帮助你。我将其添加到我的答案中。
leemes 的回答给了我一些见解,我设法在使用自定义 SizeGrip 控件的其他控件中调整布局内的 QTextWidget 的大小。请注意,至少应该有一个滚动条可见,以便有可见的尺寸夹点。
有必要重新实现小部件的sizeHint() 方法:
QSize MultilineTextEdit::sizeHint() const
{
return size();
}
然后在我添加的 SizeGrip 小部件的 mouseMoveEvent() 末尾
void SizeGrip::mouseMoveEvent(QMouseEvent * e)
{
// note that this is not the full code of the method
...
// save the old minimum and maximum size of the widget (w) resized by the grip
QSize oldMin = w->minimumSize();
QSize oldMax = w->maximumSize();
w->setFixedSize(nr.size()); // nr is the new rect of the widget
w->setMinimumSize(oldMin);
w->setMaximumSize(oldMax);
}
SizeGrip 小部件的灵感来自直接在顶级父窗口上运行的 QSizeGrip 类。 SizeGrip 改为在其直接父小部件上运行。
【讨论】: