QtQuick:从c++创建组件

QtQuick: create component from C++

本文关键字:创建组 组件 创建 c++ QtQuick      更新时间:2023-10-16

我有一个问题与QQuickView实例化组件从c++…下面是我的代码:

类定义(vviewerqml.h):

class VViewerQml : public QObject
{
    Q_OBJECT
public:
    explicit VViewerQml(QSettings &systemSettings, QObject *parent = 0);
    ~VViewerQml();
protected slots:
    void onViewStatusChanged(QQuickView::Status status);
protected:
    QString _qmlFolder;
    QQuickView _view;
};

类实现(vviewerqml.cpp):

#include "vviewerqml.h"
VViewerQml::VViewerQml(QSettings &systemSettings, QObject *parent) :
    QObject(parent)
{
    // Initialize viewer reading from settings file
    _qmlFolder = "/my/path/to/qml/files";
    // Initialize the source
    connect(&_view, SIGNAL(statusChanged(QQuickView::Status)),
        this, SLOT(onViewStatusChanged(QQuickView::Status)));
    _view.setSource(QUrl::fromLocalFile(QDir(_qmlFolder).filePath("Main.qml")));
    // Show the viewer
    _view.show();
}
VViewerQml::~VViewerQml()
{
    // Close the viewer
    _view.close();
}
void VViewerQml::onViewStatusChanged(QQuickView::Status status)
{
    if(status == QQuickView::Ready)
    {
        QQmlComponent *c =
            new QQmlComponent(_view.engine(),
            QDir(_qmlFolder).filePath("TextLegacy.qml"));
        QQuickItem *i = qobject_cast<QQuickItem*>(c->create());
        QQmlEngine::setObjectOwnership(i, QQmlEngine::CppOwnership);
        i->setParent(_view.rootObject());
        i->setVisible(true);
    }
}

这是我的Main.qml:

import QtQuick 2.0
Rectangle {
    width: 1024
    height: 768
    color: "#000000"
    Text {
        x: 0
        y: 0
        color: "#ffffff"
        text: "Main page"
    }
}

这是我的TextLegacy.qml:

import QtQuick 2.0
Item {
    Rectangle {
        x: 0
        y: 0
        width: 100
        height: 50
        color: "#ff0000"
    }
}

我的代码工作得很好,直到Main.qml的加载:QML查看器在屏幕上打开,我可以在屏幕上阅读文本"主页"(白色对黑色)…但不幸的是,我无法加载TextLegacy.qml…如果我在onViewStatusChanged函数中设置了一个断点,执行就会到达那个点…调试控制台中没有显示任何可见的错误。但是我无法在屏幕上看到TextLegacy.qml提供的红色矩形…

我错过了什么?有人能帮帮我吗?

好的,我自己找到了解决方案:我把setParentsetParentItem混淆了……正确的代码是:

void VViewerQml::onViewStatusChanged(QQuickView::Status status)
{
    if(status == QQuickView::Ready)
    {
        QQmlComponent *c = new QQmlComponent(_view.engine(),
            QUrl::fromLocalFile(QDir(_qmlFolder).filePath("TextLegacy.qml")));
        QQuickItem *i = qobject_cast<QQuickItem*>(c->create());
        QQmlEngine::setObjectOwnership(i, QQmlEngine::CppOwnership);
        i->setParent(this);
        i->setVisible(true);
        i->setParentItem(_view.rootObject());
    }
}

实际上i->setParent(this);i的父对象定义为QObject(例如,用于删除目的),而i->setParentItem(_view.rootObject());实际上将对象添加到场景中,作为场景根对象的子对象。