Dear all,

I have a C++ application that dynamically reads a .qml file and and uses it to create a QQuickWidget. Inside my .qml there is a function "getLabel()" that is used for the creation of the UI element. However, I also need to call this function from C++ code directly. Unfortunately, I am running out of ideas on how to acomplish that. I am convinced that the QQmlEngine of the QQuickWidget that I use must know the function "getLabel()" from the .qml file because it is called in order to set the text property of the label. So, how can I acces this function from C++?
I have attached a minimal working example to show what I have done so far:

QMLtest.pro
Qt Code:
  1. QT += core gui quickwidgets qml quick
  2.  
  3. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
  4.  
  5. CONFIG += c++11
  6.  
  7. # You can make your code fail to compile if it uses deprecated APIs.
  8. # In order to do so, uncomment the following line.
  9. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
  10.  
  11. SOURCES += \
  12. main.cpp \
  13. mainwindow.cpp
  14.  
  15. HEADERS += \
  16. mainwindow.h
  17.  
  18. RESOURCES += qml.qrc
  19.  
  20. # Default rules for deployment.
  21. qnx: target.path = /tmp/$${TARGET}/bin
  22. else: unix:!android: target.path = /opt/$${TARGET}/bin
  23. !isEmpty(target.path): INSTALLS += target
To copy to clipboard, switch view to plain text mode 


main.cpp
Qt Code:
  1. #include "mainwindow.h"
  2.  
  3. #include <QApplication>
  4.  
  5. int main(int argc, char *argv[])
  6. {
  7. QApplication a(argc, argv);
  8. MainWindow w;
  9. w.show();
  10. return a.exec();
  11. }
To copy to clipboard, switch view to plain text mode 


mainwindow.h
Qt Code:
  1. #ifndef MAINWINDOW_H
  2. #define MAINWINDOW_H
  3.  
  4. #include <QMainWindow>
  5.  
  6. QT_BEGIN_NAMESPACE
  7. namespace Ui { class MainWindow; }
  8. QT_END_NAMESPACE
  9.  
  10. class MainWindow : public QMainWindow
  11. {
  12. Q_OBJECT
  13.  
  14. public:
  15. MainWindow(QWidget *parent = nullptr);
  16. ~MainWindow();
  17.  
  18. private:
  19. void setupUi();
  20.  
  21. Ui::MainWindow *ui;
  22. };
  23. #endif // MAINWINDOW_H
To copy to clipboard, switch view to plain text mode 



mainwindow.cpp
Qt Code:
  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3.  
  4. #include <QQuickWidget>
  5. #include <QQmlError>
  6. #include <QQmlEngine>
  7.  
  8. #include <QHBoxLayout>
  9.  
  10. MainWindow::MainWindow(QWidget *parent)
  11. : QMainWindow(parent)
  12. , ui(new Ui::MainWindow)
  13. {
  14. setupUi();
  15. }
  16.  
  17. MainWindow::~MainWindow()
  18. {
  19. delete ui;
  20. }
  21.  
  22.  
  23. void MainWindow::setupUi()
  24. {
  25. QWidget* mainWidget = new QWidget(this);
  26. QHBoxLayout* layout = new QHBoxLayout(mainWidget);
  27.  
  28. QQuickWidget* quickWidget = new QQuickWidget(mainWidget);
  29. layout->addWidget(quickWidget);
  30. quickWidget->setSource(QUrl::fromLocalFile(":/main.qml"));
  31. foreach(QQmlError err, quickWidget->errors()) {
  32. qDebug() << err.toString() << "\n";
  33. qDebug() << err.url() << "\n";
  34. qDebug() << err.description() << "\n";
  35. qDebug() << err.line() << "\n";
  36. }
  37.  
  38. setCentralWidget(mainWidget);
  39.  
  40. QQmlEngine* engine = quickWidget->engine();
  41.  
  42.  
  43. engine->dumpObjectInfo();
  44. engine->dumpObjectTree();
  45.  
  46.  
  47. QJSValue gobalObject = engine->globalObject();
  48. qDebug() << gobalObject.hasProperty("getLabel()");
  49. qDebug() << gobalObject.hasProperty("Rectangle");
  50. qDebug() << gobalObject.hasProperty("rectangleMain");
  51. qDebug() << gobalObject.hasOwnProperty("getLabel()");
  52. qDebug() << gobalObject.hasOwnProperty("Rectangle");
  53. qDebug() << gobalObject.hasOwnProperty("rectangleMain");
  54.  
  55.  
  56. //QQmlContext *QQmlEngine::rootContext() const
  57.  
  58. QList<QByteArray> propNames = engine->dynamicPropertyNames();
  59. foreach( QByteArray ba, propNames ) {
  60. qDebug() << ba;
  61. }
  62.  
  63.  
  64. QJSValue functionResult = engine->evaluate("getLabel()");
  65. qDebug() << functionResult.toString();
  66.  
  67.  
  68. functionResult = engine->evaluate("Rectangle.getLabel()");
  69. qDebug() << functionResult.toString();
  70.  
  71. functionResult = engine->evaluate("rectangleMain.getLabel()");
  72. qDebug() << functionResult.toString();
  73.  
  74.  
  75.  
  76. QJSEngine* jsEngine = qobject_cast<QJSEngine*>(engine);
  77. if( !jsEngine ) {
  78. return;
  79. }
  80.  
  81. functionResult = jsEngine->evaluate("getLabel()");
  82. qDebug() << functionResult.toString();
  83.  
  84.  
  85. functionResult = jsEngine->evaluate("Rectangle.getLabel()");
  86. qDebug() << functionResult.toString();
  87.  
  88. functionResult = jsEngine->evaluate("rectangleMain.getLabel()");
  89. qDebug() << functionResult.toString();
  90.  
  91. //Read the qml file
  92. QString path = ":/main.qml";
  93. if( !QFile::exists(path) ) {
  94. return;
  95. }
  96. QFile scriptFile(path);
  97. if (!scriptFile.open(QIODevice::ReadOnly)) {
  98. return;
  99. }
  100. QTextStream stream(&scriptFile);
  101. QString result = stream.readAll();
  102. scriptFile.close();
  103.  
  104.  
  105. engine->evaluate(result);
  106. functionResult = engine->evaluate("getLabel()");
  107. qDebug() << functionResult.toString();
  108. }
To copy to clipboard, switch view to plain text mode 


qml.qrc
Qt Code:
  1. <RCC>
  2. <qresource prefix="/">
  3. <file>main.qml</file>
  4. </qresource>
  5. </RCC>
To copy to clipboard, switch view to plain text mode 

main.qml
Qt Code:
  1. import QtQuick 2.12
  2. //import QtQuick.Window 2.12
  3. //import Qt.labs.qmlmodels 1.0
  4. import QtQuick.Controls 2.15
  5.  
  6. Rectangle {
  7. id: rectangleMain
  8. width: 500
  9. height: 500
  10. visible: true
  11.  
  12. function getLabel() {
  13. return "hello world!";
  14. }
  15.  
  16. Label {
  17. text: getLabel()
  18. }
  19.  
  20. }
To copy to clipboard, switch view to plain text mode