在 Qt 中获取父布局

发布于 2024-08-24 15:10:29 字数 304 浏览 8 评论 0原文

有什么方法可以检索 Qt 中小部件的父布局吗?

由于逻辑原因,QObject::parent() 将不起作用。

我确信该小部件有一个父布局,因为我将其添加到了代码前面的布局中。现在,我的窗口中有许多其他布局,虽然我可以跟踪它们,但我只想知道是否有一种简单而干净的方法可以使用 Qt API 获取父布局。

我将小部件添加到布局中,如下所示:

QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(button);

Is there any way to retrieve the parent layout of a widget in Qt?

QObject::parent() won't work, for logical reasons.

I'm positive the widget has a parent layout, because I added it to a layout earlier in the code. Now, I have many other layouts in the window and while it is possible for me to keep track of them, I just want to know if there is an easy and clean way to get the parent layout by using the Qt API.

I'm adding the widget to the layout like this:

QHBoxLayout* layout = new QHBoxLayout;
layout->addWidget(button);

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

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

发布评论

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

评论(7

对岸观火 2024-08-31 15:10:29

好吧,不幸的是 QWidget API 不提供 QWidget: :parentLayout() 方法,但这里是一个经过测试且有效的实现。

用法:QLayout *layout =parentLayout(myWidget);

QLayout *parentLayout(const QWidget *widget, QLayout *layout) {
    int itemCount = layout ? layout->count() : 0;
    for (int i = 0; i < itemCount; i++) {
        if (layout->itemAt(i)->widget() == widget) {
            return layout;
        } else if (QLayout *itemLayout = parentLayout(widget, layout->itemAt(i)->layout())) {
            return itemLayout;
        }
    }
    return nullptr;
}

QLayout *parentLayout(const QWidget *widget) {
    QLayout *layout = widget->parentWidget() ? widget->parentWidget()->layout() : nullptr;
    return parentLayout(widget, layout);
}

Well, the QWidget API unfortunately doesn't provide a QWidget::parentLayout() method, but here is a tested and working implementation.

Usage: QLayout *layout = parentLayout(myWidget);

QLayout *parentLayout(const QWidget *widget, QLayout *layout) {
    int itemCount = layout ? layout->count() : 0;
    for (int i = 0; i < itemCount; i++) {
        if (layout->itemAt(i)->widget() == widget) {
            return layout;
        } else if (QLayout *itemLayout = parentLayout(widget, layout->itemAt(i)->layout())) {
            return itemLayout;
        }
    }
    return nullptr;
}

QLayout *parentLayout(const QWidget *widget) {
    QLayout *layout = widget->parentWidget() ? widget->parentWidget()->layout() : nullptr;
    return parentLayout(widget, layout);
}
巡山小妖精 2024-08-31 15:10:29

(更新的答案)

我想这是不容易实现的。由于 Widget 在技术上可以包含在多个布局中(例如,在垂直布局内对齐的水平布局)。

请记住,如果 QWidget 在布局中对齐,其父级不会改变。

那么你可能必须自己跟踪这一点。

(Updated answer)

I guess it is not easily possible then. Since a Widget can be technically contained in multiple layouts (a horizontal layout which is aligned inside a vertical layout, for instance).

Just remember that a QWidget's parent does not change if it is aligned in a layout.

You possibly have to keep track of that yourself, then.

过度放纵 2024-08-31 15:10:29

只需使用:

QHBoxLayout* parentLayout = button->parentWidget()->layout();

我假设 button 是包含 layout 的小部件的子级,而 layout 又包含 buttonbutton->parentWidget() 返回指向按钮 parent->layout() 的 widget 的指针code> 返回指向父级布局的指针。

Simply use:

QHBoxLayout* parentLayout = button->parentWidget()->layout();

I assume button is a child of the widget which contains the layout which contains button. button->parentWidget() returns a pointer to the widget of the button's parent and ->layout() returns the pointer to the layout of the parent.

一场春暖 2024-08-31 15:10:29

经过一番探索,我找到了问题的“部分”解决方案。

如果您要创建布局并用它管理小部件,则可以稍后在代码中使用 Qt 的动态属性来检索此布局。现在,要使用 QWidget::setProperty(),您要存储的对象需要是已注册的元类型。指向 QHBoxLayout 的指针不是注册的元类型,但有两种解决方法。最简单的解决方法是通过在代码中的任何位置添加以下内容来注册对象:

Q_DECLARE_METATYPE(QHBoxLayout*)

第二个解决方法是包装对象:

struct Layout {
    QHBoxLayout* layout;
};
Q_DECLARE_METATYPE(Layout)

一旦对象是已注册的元类型,您可以通过这种方式保存它:

QHBoxLayout* layout = new QHBoxLayout;
QWidget* widget = new QWidget;
widget->setProperty("managingLayout", QVariant::fromValue(layout));
layout->addWidget(widget);

或者如果您使用了第二种解决方法,则可以这样 保存:

QHBoxLayout* layout = new QHBoxLayout;
QWidget* widget = new QWidget;
Layout l;
l.layout = layout;
widget->setProperty("managingLayout", QVariant::fromValue(l));
layout->addWidget(widget);

稍后当您需要检索布局时,可以通过以下方式检索它:

QHBoxLayout* layout = widget->property("managingLayout").value<QHBoxLayout*>();

或者像这样:

Layout l = widget->property("managingLayout").value<Layout>();
QHBoxLayout* layout = l.layout;

这种方法仅适用于您创建布局时。如果您没有创建布局并设置它,那么以后就没有简单的方法来检索它。此外,您还必须跟踪布局并在必要时更新管理布局属性。

After some exploration, I found a "partial" solution to the problem.

If you are creating the layout and managing a widget with it, it is possible to retrieve this layout later in the code by using Qt's dynamic properties. Now, to use QWidget::setProperty(), the object you are going to store needs to be a registered meta type. A pointer to QHBoxLayout is not a registered meta type, but there are two workarounds. The simplest workaround is to register the object by adding this anywhere in your code:

Q_DECLARE_METATYPE(QHBoxLayout*)

The second workaround is to wrap the object:

struct Layout {
    QHBoxLayout* layout;
};
Q_DECLARE_METATYPE(Layout)

Once the object is a registered meta type, you can save it this way:

QHBoxLayout* layout = new QHBoxLayout;
QWidget* widget = new QWidget;
widget->setProperty("managingLayout", QVariant::fromValue(layout));
layout->addWidget(widget);

Or this way if you used the second workaround:

QHBoxLayout* layout = new QHBoxLayout;
QWidget* widget = new QWidget;
Layout l;
l.layout = layout;
widget->setProperty("managingLayout", QVariant::fromValue(l));
layout->addWidget(widget);

Later when you need to retrieve the layout, you can retrieve it this way:

QHBoxLayout* layout = widget->property("managingLayout").value<QHBoxLayout*>();

Or like this:

Layout l = widget->property("managingLayout").value<Layout>();
QHBoxLayout* layout = l.layout;

This approach is applicable only when you created the layout. If you did not create the layout and set it, then there is not a simple way of retrieving it later. Also you will have to keep track of the layout and update the managingLayout property when necessary.

三生一梦 2024-08-31 15:10:29

使用 widget.parent().layout() 和搜索暴力(包括递归)是我唯一的建议。也许你可以搜索“姓名”。

use widget.parent().layout() and search brute force (recursion included) is my only advice. Maybe you can search be "name".

云之铃。 2024-08-31 15:10:29

你试过这个吗?不要忘记检查 NULL。

QLayout *parent_layout = qobject_cast< QLayout* >( parent() );

如果 parent_layout 等于 NULL,则父窗口小部件不是布局。

Have you tried this? Don't forget to check for NULL.

QLayout *parent_layout = qobject_cast< QLayout* >( parent() );

If parent_layout equals NULL, then the parent widget is not a layout.

寄居者 2024-08-31 15:10:29

您尝试过QWidget::layout()吗?

Have you tried QWidget::layout() ?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文