当子元素大小调整时,如何强制进行布局更新/调整大小?

16

我有一个自定义的 QTextEdit 小部件,它在角落里有自己的调整大小手柄。我可以成功地调整文本小部件的大小,但是它所在的布局并没有随着文本编辑器的调整而改变。

是否有一种方法可以告诉管理布局根据其小部件中的独立大小变化重新计算自身布局?

2个回答

29
布局将尊重其子代的sizeHint()minimalSizeHint()(而不是它们的size())。因此,您应该重新实现这两个虚拟方法,并返回您想要强制使用的大小。每当您的大小提示更改时,您应该在自己的小部件上调用updateGeometry(),以触发包含小部件的布局的更新。请参阅文档: 为了强制小部件的最小尺寸,实现minimumSizeHint() 并返回所需的最小尺寸;为了强制一固定的大小,将两者都实现并返回相同的大小。建议还阅读以下文档页面中的“布局管理”部分:

“自定义布局中的小部件”

如果您制作自己的窗口小部件类,还应该通知它的布局属性。如果小部件具有Qt的一种布局,则已经处理了此问题。如果小部件没有任何子部件或使用手动布局,则可以使用以下任意或所有机制更改小部件的行为:
- 重新实现QWidget::sizeHint()以返回小部件的首选大小。 - 重新实现QWidget::minimumSizeHint()以返回小部件可以具有的最小大小。 - 调用QWidget::setSizePolicy()指定小部件的空间要求。
每当大小提示、最小大小提示或大小策略更改时,请调用QWidget::updateGeometry()。这将导致布局重新计算。多个连续的QWidget::updateGeometry()调用仅会引起一次布局重新计算。 更新(参见评论): 您还可以通过调用以下命令之一来强制设置大小(或仅高度/宽度):
QWidget::setFixedSize(QSize);
QWidget::setFixedHeight(int);
QWidget::setFixedWidth(int);

据我所知,这些方法只是将大小提示设置为给定值,并调用updateGeometry()。但也许它们做了更多的事情,因为(根据评论所示),这是我找到的唯一解决问题的方法。


你是否尝试在此之后调用 updateGeometry() 函数?你使用的是哪种布局类型?你是否仔细检查了将小部件添加到布局中时是否有任何错误?在不使用缩放手柄的情况下,你的 QTextEdit 是否像往常一样对布局更改(父窗口小部件的大小调整)做出反应? - leemes
好的,这就是我正在做的事情。我不是Qt方面的专家或者什么的。http://pastebin.com/mRNLZEAp我删掉了所有不相关的内容。如果我在任何地方调用updateGeometry(),我就失去了调整文本编辑器大小的能力。 - George
我正在进行一些测试,我猜问题在于调整大小和光标跟踪操作互相干扰。给我10分钟,我们看看我能否解决这个问题。 - leemes
5
好的,我用setFixedHeight替代了大小提示来解决这个问题。在这种情况下不需要使用updateGeometry。删除大小提示相关的内容,将两行代码 setGeometry( x(), y(), width(), height()-h_diff );size_hint_ = QSize( width(), height()-h_diff ); 替换为简单的调用 setFixedHeight(height()-h_diff);。另一个问题出现了:如果你缩小文本区域,外部部件(即窗口)不会跟着一起缩小。你应该把整个东西放在一个能够尽可能保持小尺寸的部件中。希望我可以帮到你,我会把它加入我的回答中。 - leemes
谢谢。对我真正有用的东西只有三行代码,写在最后。 - Tab
显示剩余3条评论

1
leemes的回答给了我一些启示,我成功地使用自定义SizeGrip控件在布局中调整了QTextWidget以及其他控件的大小。请注意,至少应该有一个滚动条可见才能看到可见大小的grip。
需要重新实现小部件的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则在其直接父部件上操作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接