如果QML组件是从C++

发布于 2025-01-30 15:21:29 字数 2443 浏览 3 评论 0原文

我的目标是创建一个自定义组件(让我们称其为componentloader),该组件可以通过委托来实例化另一个组件(我们称其为delegatecomponent)。

问题在于,创建后未显示delegatecompont的实例(白屏幕)。注意:tst_component已加载消息存在,这意味着delegatecomponent实例实际创建了。

这是一个最小示例:

main.qml

ApplicationWindow {
    id: mainWindow
    width: 640
    height: 480
    visible: true

    Component {
        id: tst_component

        Rectangle {
            anchors.fill: parent

            Component.onCompleted: {
                console.debug("tst_component is loaded");
            }

            Label {
                text: "hello world"
                anchors.centerIn: parent
            }
        }
    }

// doesn't work
    ComponentLoader {
        anchors.fill: parent
        delegate: tst_component
    }

// works
//    Loader {
//        anchors.fill: parent
//        sourceComponent: tst_component
//    }
}

componentloader.h + componentloader.cpp

#pragma once
#include <QQuickItem>

class ComponentLoader : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)

public:
    QQmlComponent* delegate() const;
    void setDelegate(QQmlComponent*);

signals:
    void delegateChanged();

private:
    void generate();

protected:
    void componentComplete() override;

private:
    QQmlComponent* mDelegate = nullptr;
};

// componentloader.cpp
#include "componentloader.h"
#include <QtWidgets/QtWidgets>
#include <QtQmlModels/QtQmlModels>
#include <QQuickWindow>

QQmlComponent* ComponentLoader::delegate() const
{
    return mDelegate;
}

void ComponentLoader::setDelegate(QQmlComponent* delegate)
{
    if (delegate != mDelegate)
    {
        mDelegate = delegate;
        emit delegateChanged();
    }
}

void ComponentLoader::componentComplete()
{
    QQuickItem::componentComplete();
    generate();
}

void ComponentLoader::generate()
{
    QQmlEngine* engine = qmlEngine(this);
    QQmlContext* root_ctx = engine->rootContext();
    QQmlContext* ctx = new QQmlContext(root_ctx);

    QObject* item = mDelegate->create(ctx);
    QQuickItem* quickItem = qobject_cast<QQuickItem*>(item);

    QQuickItem* quickParent = qobject_cast<QQuickItem*>(parent());
    quickItem->setParent(quickParent);
    quickItem->setParentItem(quickParent);
}

My goal is to create a custom Component (lets call it ComponentLoader) which can instantiate another component (lets call it DelegateComponent) via delegate.

The problem is that the instance of DelegateComponent isn't displayed after is was created (white screen). Note: tst_component is loaded message IS present which means that DelegateComponent instance was actually created.

Here is a minimal example:

main.qml

ApplicationWindow {
    id: mainWindow
    width: 640
    height: 480
    visible: true

    Component {
        id: tst_component

        Rectangle {
            anchors.fill: parent

            Component.onCompleted: {
                console.debug("tst_component is loaded");
            }

            Label {
                text: "hello world"
                anchors.centerIn: parent
            }
        }
    }

// doesn't work
    ComponentLoader {
        anchors.fill: parent
        delegate: tst_component
    }

// works
//    Loader {
//        anchors.fill: parent
//        sourceComponent: tst_component
//    }
}

componentloader.h + componentloader.cpp

#pragma once
#include <QQuickItem>

class ComponentLoader : public QQuickItem
{
    Q_OBJECT
    Q_PROPERTY(QQmlComponent* delegate READ delegate WRITE setDelegate NOTIFY delegateChanged)

public:
    QQmlComponent* delegate() const;
    void setDelegate(QQmlComponent*);

signals:
    void delegateChanged();

private:
    void generate();

protected:
    void componentComplete() override;

private:
    QQmlComponent* mDelegate = nullptr;
};

// componentloader.cpp
#include "componentloader.h"
#include <QtWidgets/QtWidgets>
#include <QtQmlModels/QtQmlModels>
#include <QQuickWindow>

QQmlComponent* ComponentLoader::delegate() const
{
    return mDelegate;
}

void ComponentLoader::setDelegate(QQmlComponent* delegate)
{
    if (delegate != mDelegate)
    {
        mDelegate = delegate;
        emit delegateChanged();
    }
}

void ComponentLoader::componentComplete()
{
    QQuickItem::componentComplete();
    generate();
}

void ComponentLoader::generate()
{
    QQmlEngine* engine = qmlEngine(this);
    QQmlContext* root_ctx = engine->rootContext();
    QQmlContext* ctx = new QQmlContext(root_ctx);

    QObject* item = mDelegate->create(ctx);
    QQuickItem* quickItem = qobject_cast<QQuickItem*>(item);

    QQuickItem* quickParent = qobject_cast<QQuickItem*>(parent());
    quickItem->setParent(quickParent);
    quickItem->setParentItem(quickParent);
}

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

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

发布评论

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

评论(1

薆情海 2025-02-06 15:21:29

您的QuickParent指针将qobject parent()值而不是qquickitem parentItem()值。

当我尝试您的代码时,只需将其更改为对我来说有用:

QQuickItem* quickParent = qobject_cast<QQuickItem*>(parentItem());

我也认为您根本不需要致电SetParent()。只是setParentItem()。

Your quickParent pointer is taking the QObject parent() value instead of the QQuickItem parentItem() value.

Simply changing it to this worked for me when I tried your code:

QQuickItem* quickParent = qobject_cast<QQuickItem*>(parentItem());

I also don't think you need to call setParent() at all. Just setParentItem().

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