如何更新 QLayout 并在返回之前获取新尺寸?

发布于 2024-12-11 10:29:50 字数 435 浏览 0 评论 0原文

这让我抓狂。我有一个自定义菜单类,当设置为可见时,会显示位于特定文件夹中的项目列表。当按下硬件按钮时,我的应用程序会获取最新的项目列表,用它们填充菜单,然后返回。

显示这些项目的菜单使用充满自定义小部件的 QListWidget。每个小部件都包含一个或多个水平布局的 QLabel,并在显示菜单时创建。为了根据可用的菜单宽度调整显示的文本,我需要在根据布局调整大小之后、但在菜单对用户可见之前获取 QLabel 的大小。问题是,直到构建列表的所有函数都返回后,我的布局才会更新。

我已经尝试过 QApplication::ProcessEvents() 和布局更新函数,但它们都没有在返回之前更新我的 QLabels 的值。我可以在最初按下按钮时设置 QTimer,并让它显示菜单、更新项目并自行停止,但这似乎是一个糟糕的解决方案。

任何帮助将不胜感激!我花了一天的大部分时间在这上面。

马龙

This is driving me nuts. I have a custom menu class that, when set visible, shows a list of items located in a particular folder. When a hardware button is pressed, my application gets the latest list of items, populates the menu with them, and returns.

The menu displaying these items uses a QListWidget filled with custom widgets. Each of the widgets contains one or more QLabels in a horizontal layout, and is created at the time the menu is shown. In order to adjust the text displayed based on the menu width available, I need to get the size of the QLabel AFTER it has been resized according to the layout, but before the menu becomes visible to the user. The problem is, my layout does not get updated until all of the functions constructing my list return.

I have tried QApplication::ProcessEvents() and the layout update functions, but none of them have updated the values of my QLabels before returning. I can set a QTimer when the button is initially pressed, and have it show the menu, update the items, and stop itself, but that seems like a terrible solution.

Any help would really be appreciated! I've spent most of a day on this.

Marlon

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

葬シ愛 2024-12-18 10:29:50

我遇到了这个确切的问题,但在互联网上找不到答案。调用 Layout.update()Layout.activate()widget.adjustSize() (在各个​​地方都建议)都没有工作。

我有一个具有垂直布局的小部件,我想向其中添加 QLabel,然后立即使用 QLabel 的大小。

唯一可靠的工作是,

layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();

布局似乎不会重新计算,直到您从函数返回并允许 Qt 事件循环继续进行或自己手动调用 show()

I had this exact problem and could not find an answer anywhere on the Internet. Calling Layout.update(), Layout.activate(), or widget.adjustSize() (all suggested in various places) all did not work.

I had a widget with a vertical layout that I wanted to add a QLabel to and then immediately use the size of the QLabel.

The only thing that worked reliably was

layout->addWidget(myLabel);
myLabel->show();
size = myLabel->size();

It would seem that layouts will just not recalculate until you either return from a function and allow the Qt event loop to progress or manually call show() yourself.

酒解孤独 2024-12-18 10:29:50

如何更新 QLayout 并在返回之前获取新尺寸?

不。你不应该这样做。它会让你“发疯”,因为你正在做相反的事情。布局更新是从事件循环异步处理的。不要立即获取布局尺寸,而是将自己设置为系统的一部分。一些选项是:

  1. 实现一个自定义小部件,该小部件将与布局正确交互,并不断增长以填充布局的可用宽度。也许您需要的只是大小策略和删除文本的方法?

  2. 创建一个考虑到您的用例的特殊属性的自定义布局。

How to update a QLayout and get the new dimensions before returning?

Don't. You're not meant to do that. It'll drive you "nuts" because you're doing it backwards. Layout updates are handled asynchronously from the event loop. Instead of getting layout dimensions right away, set yourself up to be part of the system. Some options are:

  1. Implement a custom widget that will interact properly with the layout, growing to fill the available width of the layout. Perhaps all you need is a size policy and a way to elide text?

  2. Make a custom layout that takes the special properties of your use case into account.

婴鹅 2024-12-18 10:29:50

您想在父窗口小部件上调用QWidget::adjustSize()。这将强制重新计算布局。

You want to call QWidget::adjustSize() on your parent widget. This will force the layout recalculations.

美男兮 2024-12-18 10:29:50

您是否尝试过使用 layout()->update();

Have you tried using layout()->update(); ?

嘿咻 2024-12-18 10:29:50

我已经尝试了很多,但在 Qt 5.15 上没有任何效果。
只发明了一个小补丁 - 创建计时器并在 20 毫秒后获取大小:

QTimer::singleShot(20, this, [this]
{
    const auto height = myLayout->contentsRect().height();
    // ...
});

I've tried many but nothing works for me on Qt 5.15.
Only invented little patch - create timer and get size after 20 msec:

QTimer::singleShot(20, this, [this]
{
    const auto height = myLayout->contentsRect().height();
    // ...
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文