如果 QML 组件是从 C++ 以编程方式创建的,则不显示该组件



我的目标是创建一个自定义组件(姑且叫它ComponentLoader),它可以通过委托实例化另一个组件(姑且叫它DelegateComponent)。

问题是DelegateComponent的实例创建后不显示(白屏)。注意:tst_component is loaded消息存在,这意味着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);
}

您的quickParent指针正在使用QObject parent()值而不是QQuickItem parentItem()值。

当我尝试您的代码时,简单地将其更改为以下内容:

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

我也不认为你需要调用setParent()。只是setParentItem () .

最新更新