Custom c++ QQuickItem is not visible in QML rendering
-
The custom item is registered and loads in the QML with no problem. I just can't see any output. One problem is that it has no height and width. Though, I set it manually to bypass that problem for now. The next problem is that it does not render. I have debugged the code, and I found the instantiation of the QComponent works correctly (by checking the children in the debugger). The width is set and the children are present before it's parent is set to the engine and it's parent item is set to the RootedLoader. Any help with this problem would be greatly appreciated. Thanks!
RootedLoader.h:
#ifndef ROOTEDLOADER_H #define ROOTEDLOADER_H #include <QQmlEngine> #include <QQuickItem> class RootedLoader : public QQuickItem { Q_OBJECT Q_PROPERTY( QString root READ root WRITE set_root NOTIFY root_changed REQUIRED ) Q_PROPERTY( QString location READ location WRITE set_location NOTIFY location_changed ) QML_ELEMENT protected: QString _root; QString _location; public: RootedLoader( QQuickItem* parent = nullptr ); QString location() const; void set_location( const QString& location ); QString root() const; void set_root( const QString& root ); protected: virtual void componentComplete() override; void load(); signals: void root_changed( const QString& location ); void location_changed( const QString& location ); }; #endif // ROOTEDLOADER_H```RootedLoader.cpp:
#include "RootedLoader.h" #include <QQmlContext> #include <QQmlComponent> #include "application_engine.h" RootedLoader::RootedLoader( QQuickItem* parent ): QQuickItem( parent ) { setFlag( QQuickItem::ItemHasContents, true ); } QString RootedLoader::location() const { return _location; } void RootedLoader::set_location( const QString& location ) { _location = location; if( isComponentComplete() ) load(); } QString RootedLoader::root() const { return _root; } void RootedLoader::set_root( const QString& root ) { _root = root; } void RootedLoader::componentComplete() { load(); } void RootedLoader::load() { auto item_width = width(); auto item_height = height(); qDebug() << item_width; qDebug() << item_height; // auto url = QUrl( _root + _location ); auto url_string = QString( "qrc:/law/lawtree/testpage.qml" ); auto url = QUrl( url_string ); QQmlComponent* location_component = new QQmlComponent( application_engine::engine(), url ); QQuickItem* instance = qobject_cast<QQuickItem*>( location_component->create() ); if( childItems().count() > 0 ) { QQuickItem* item = this->childItems().at( 0 ); item->setParentItem( NULL ); instance->setParentItem( this ); instance->setParent( application_engine::engine() ); item->setParent( NULL ); item->deleteLater(); } else { instance->setParent( application_engine::engine() ); instance->setParentItem( this ); } }main.qml:
import QtQuick import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import CustomComponents 1.0 import "." ApplicationWindow { title: qsTr( "Law and Order" ) width: 540 height: 960 visible: true StackLayout { id: view_stack anchors.fill: parent currentIndex: 1 LawTree { id: law_tree } Rectangle { border.width: 4 border.color: "blue" Column { anchors.fill: parent Text { text: "testing" } // TestQuickItem // { // anchors.centerIn: parent // width: parent.width/2 // height: parent.height/2 // } // note that TestQuickItem displays without a problem using updatePaintNode to paint a triangle RootedLoader { id: loader root: "qrc:/law/lawtree" location: "/testpage.qml" anchors.fill: parent width: 200 height: 400 } } } } }testpage.qml (loaded from RootedLoader):
Item { id: view property string law_description : "law description ****" property string order_description : "order description ****" property string coordination_description : "coordination description ****" property string preawareness_description : "preawareness description ****" anchors.fill: parent Rectangle { anchors.fill: parent border.color: "red" border.width: 4 Column { anchors.fill: parent Row { Text { text: "law:" } Text { id: law_description_text text: view.law_description color: "blue" } } Row { Text { text: "order:" } Text { id: order_description_text text: view.order_description color: "blue" } } Row { Text { text: "coordination:" } Text { id: coordination_description_text text: view.coordination_description color: "blue" } } Row { Text { text: "preawareness:" } Text { id: preawareness_description_text text: view.preawareness_description color: "blue" } } } } } -
The custom item is registered and loads in the QML with no problem. I just can't see any output. One problem is that it has no height and width. Though, I set it manually to bypass that problem for now. The next problem is that it does not render. I have debugged the code, and I found the instantiation of the QComponent works correctly (by checking the children in the debugger). The width is set and the children are present before it's parent is set to the engine and it's parent item is set to the RootedLoader. Any help with this problem would be greatly appreciated. Thanks!
RootedLoader.h:
#ifndef ROOTEDLOADER_H #define ROOTEDLOADER_H #include <QQmlEngine> #include <QQuickItem> class RootedLoader : public QQuickItem { Q_OBJECT Q_PROPERTY( QString root READ root WRITE set_root NOTIFY root_changed REQUIRED ) Q_PROPERTY( QString location READ location WRITE set_location NOTIFY location_changed ) QML_ELEMENT protected: QString _root; QString _location; public: RootedLoader( QQuickItem* parent = nullptr ); QString location() const; void set_location( const QString& location ); QString root() const; void set_root( const QString& root ); protected: virtual void componentComplete() override; void load(); signals: void root_changed( const QString& location ); void location_changed( const QString& location ); }; #endif // ROOTEDLOADER_H```RootedLoader.cpp:
#include "RootedLoader.h" #include <QQmlContext> #include <QQmlComponent> #include "application_engine.h" RootedLoader::RootedLoader( QQuickItem* parent ): QQuickItem( parent ) { setFlag( QQuickItem::ItemHasContents, true ); } QString RootedLoader::location() const { return _location; } void RootedLoader::set_location( const QString& location ) { _location = location; if( isComponentComplete() ) load(); } QString RootedLoader::root() const { return _root; } void RootedLoader::set_root( const QString& root ) { _root = root; } void RootedLoader::componentComplete() { load(); } void RootedLoader::load() { auto item_width = width(); auto item_height = height(); qDebug() << item_width; qDebug() << item_height; // auto url = QUrl( _root + _location ); auto url_string = QString( "qrc:/law/lawtree/testpage.qml" ); auto url = QUrl( url_string ); QQmlComponent* location_component = new QQmlComponent( application_engine::engine(), url ); QQuickItem* instance = qobject_cast<QQuickItem*>( location_component->create() ); if( childItems().count() > 0 ) { QQuickItem* item = this->childItems().at( 0 ); item->setParentItem( NULL ); instance->setParentItem( this ); instance->setParent( application_engine::engine() ); item->setParent( NULL ); item->deleteLater(); } else { instance->setParent( application_engine::engine() ); instance->setParentItem( this ); } }main.qml:
import QtQuick import QtQuick.Layouts 1.15 import QtQuick.Controls 2.15 import CustomComponents 1.0 import "." ApplicationWindow { title: qsTr( "Law and Order" ) width: 540 height: 960 visible: true StackLayout { id: view_stack anchors.fill: parent currentIndex: 1 LawTree { id: law_tree } Rectangle { border.width: 4 border.color: "blue" Column { anchors.fill: parent Text { text: "testing" } // TestQuickItem // { // anchors.centerIn: parent // width: parent.width/2 // height: parent.height/2 // } // note that TestQuickItem displays without a problem using updatePaintNode to paint a triangle RootedLoader { id: loader root: "qrc:/law/lawtree" location: "/testpage.qml" anchors.fill: parent width: 200 height: 400 } } } } }testpage.qml (loaded from RootedLoader):
Item { id: view property string law_description : "law description ****" property string order_description : "order description ****" property string coordination_description : "coordination description ****" property string preawareness_description : "preawareness description ****" anchors.fill: parent Rectangle { anchors.fill: parent border.color: "red" border.width: 4 Column { anchors.fill: parent Row { Text { text: "law:" } Text { id: law_description_text text: view.law_description color: "blue" } } Row { Text { text: "order:" } Text { id: order_description_text text: view.order_description color: "blue" } } Row { Text { text: "coordination:" } Text { id: coordination_description_text text: view.coordination_description color: "blue" } } Row { Text { text: "preawareness:" } Text { id: preawareness_description_text text: view.preawareness_description color: "blue" } } } } }@Ariyo_Walker I have exactly the same problem and I don't know how to figure it out...
I'm trying qquickPaintedItem instead of QQuickItem inherit but now I got an error Element is not CreatableAnyone have I idea how can we proceed ?
Thanks you in advance