Embedding C++ Objects into QML with Context Properties

5,280

I reused your qml file to start a fresh project in QtCreator.

Please find below the files I used to compile and use the application successfully:

the project file: test.pro

# The .cpp file which was generated for your project. Feel free to hack it.
SOURCES += main.cpp

# Please do not modify the following two lines. Required for deployment.
include(qtquick2applicationviewer/qtquick2applicationviewer.pri)
qtcAddDeployment()

HEADERS += myclass.h

myclass.h:

#include <QObject>
#include <qdebug.h>

class MyClass : public QObject
{
    Q_OBJECT

public slots:
    void doStuffFromQmlSlot()
    {
        qDebug() << Q_FUNC_INFO;
    }

public:
    MyClass()
    {
        qDebug() << Q_FUNC_INFO;
    }
};

main.cpp:

#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include <QQmlContext>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    MyClass myClass;

    QtQuick2ApplicationViewer viewer;
    viewer.rootContext()->setContextProperty("myclass", &myClass);
    viewer.setMainQmlFile(QStringLiteral("qml/main.qml"));
    viewer.showExpanded();

    return app.exec();
}

and qml/main.qml being exactly the snippet provided in your question

if you start the project using QtCreator you'll also have the qtquick2applicationviewer/ folder ready to be used. Then qmake && make && ./test will launch the application. If you click on the text element you'll get:

MyClass::MyClass() 
void MyClass::doStuffFromQmlSlot()
Share:
5,280

Related videos on Youtube

sergico
Author by

sergico

Updated on September 18, 2022

Comments

  • sergico
    sergico almost 2 years

    According to Qt5 documentation: exposing methods including qt slots all public slots of C++ classes that inherit from QObject, are accessible from QML Here what I did:

    C++

    class MyClass : public QObject
    {
        Q_OBJECT
    
    public slots:
        void doStuffFromQmlSlot()
        {
            qDebug() << Q_FUNC_INFO;
        }
    
    public:
        MyClass()
        {
            qDebug() << Q_FUNC_INFO;
        }
    };
    

    my main.cpp contains:

    MyClass myClass;
    QQmlEngine engine;
    engine.rootContext()->setContextProperty( "myclass", &myClass );
    QQmlComponent component( &engine, QUrl::fromLocalFile("qml/qtquick-01/main.qml") );
    component.create();
    

    QML

    import QtQuick 2.0
    
    Rectangle {
        width: 360
        height: 360
        Text {
            text: qsTr("Hello World")
            anchors.centerIn: parent
        }
        MouseArea {
            anchors.fill: parent
            onClicked: {
                myclass.doStuffFromQmlSlot();
    
                Qt.quit();
            }
        }
    }
    

    Actually the QtCreator seems to recognixe the exposed myclass object into the QML as it enables auto-completion of both class name (myclass) and the public slot doStuffFromQmlSlot(). When I run the application I unfortunately got the following error:

    ReferenceError: myclass is not defined

    Any clue on what I'm doing wrong?

    • sergico
      sergico over 10 years
      I posted on AskUbuntu as I found several questions regarding ubuntu-phone here. I agree that the topic is really programming specific, so the question is a good candidate for StackOverflow
    • Sylvain Pineau
      Sylvain Pineau about 10 years
      QML is a core progamming language for ubuntu & ubuntu-touch and hence is on-topic here, please re-open it.
  • sergico
    sergico over 10 years
    That worked! here what I was doing wrong: I was adding the classes to the wrong Context. Did not realized that the QtQuick2ApplicationViewer viewer is a QmlEngine as well.