How to run a C++ function in qml?



  • hi
    i want to use a function of ApplicationData class in main.qml. but i hava a error.

    main.cpp:

    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QCoreApplication>
    #include <QDebug>
    #include <QtSerialPort/QtSerialPort>
    #include <QtDeclarative/QDeclarativeContext>
    #include <QQmlContext>
    
    class ApplicationData : public QObject
    {
        Q_OBJECT public: Q_INVOKABLE QDateTime getCurrentDateTime() const {
            return QDateTime::currentDateTime();
        }
    };
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        app.setLayoutDirection(Qt::RightToLeft);
    
        ApplicationData myClass;  
    
        QQmlContext *context = new QQmlContext(engine.rootContext());
        context->setContextProperty("myClass", &myClass);
    
        return app.exec();
    }
    
    
    

    error:

    main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __cdecl ApplicationData::metaObject(void)const " (?metaObject@ApplicationData@@UEBAPEBUQMetaObject@@XZ)
    
    main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual void * __cdecl ApplicationData::qt_metacast(char const *)" (?qt_metacast@ApplicationData@@UEAAPEAXPEBD@Z)
    
    main.obj:-1: error: LNK2001: unresolved external symbol "public: virtual int __cdecl ApplicationData::qt_metacall(enum QMetaObject::Call,int,void * *)" (?qt_metacall@ApplicationData@@UEAAHW4Call@QMetaObject@@HPEAPEAX@Z)
    

    please guide me
    thanks



  • Hi,
    you need to put your ApplicationData class in its own header/source file. Otherwise the meta object compiler won't process it and thus the Q_OBJECT macro won't work.



  • This works for me:

    main.cpp

    #include <QGuiApplication>
    #include <QQmlApplicationEngine>
    #include <QtQml>
    #include <QQmlContext>
    
    #include "applicationdata.h"
    
    int main(int argc, char *argv[])
    {
        QGuiApplication app(argc, argv);
        QQmlApplicationEngine engine;
        ApplicationData data;
        engine.rootContext()->setContextProperty("appData", &data);
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        return app.exec();
    }
    

    applicationdata.h

    #ifndef APPLICATIONDATA_H
    #define APPLICATIONDATA_H
    
    #include <QObject>
    #include <QString>
    #include <QDateTime>
    
    class ApplicationData : public QObject
    {
        Q_OBJECT
    public:
        explicit ApplicationData(QObject *parent = 0);
        Q_INVOKABLE QDateTime getCurrentDateTime() const;
    
    };
    
    #endif // APPLICATIONDATA_H
    

    applicationdata.cpp

    #include "applicationdata.h"
    
    ApplicationData::ApplicationData(QObject *parent)
        : QObject(parent)
    {
    }
    
    QDateTime ApplicationData::getCurrentDateTime() const
    {
        return QDateTime::currentDateTime();
    }
    
    

    main.qml

    import QtQuick 2.3
    import QtQuick.Window 2.2
    
    Window {
        visible: true
    
        MouseArea {
            anchors.fill: parent
            onClicked: {
                Qt.quit();
            }
        }
    
        Text {
            text: appData.getCurrentDateTime()
            anchors.centerIn: parent
        }
    
    }
    


  • thanks
    i put ApplicationData class in header file.
    but i have another error.

    #ifndef ApplicationData
    #define ApplicationData
    #include <QDateTime>
    class ApplicationData : public QObject
    {
        Q_OBJECT public: Q_INVOKABLE QDateTime getCurrentDateTime() const {
            return QDateTime::currentDateTime();
        }
    };
    
    #endif // ApplicationData
    
    
    

    main.cpp:

    #include <QApplication>
    #include <QQmlApplicationEngine>
    #include <QDebug>
    #include "ApplicationData.h"
    
    int main(int argc, char *argv[])
    {
        QApplication app(argc, argv);
    
        QQmlApplicationEngine engine;
    
        engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
        app.setLayoutDirection(Qt::RightToLeft);
    
        ApplicationData myClass;
    
        QQmlContext *context = new QQmlContext(engine.rootContext());
        context->setContextProperty("myClass", &myClass);
    
        return app.exec();
    }
    
    

    error:

    error: C2027: use of undefined type 'QQmlContext'
    
    C:\Qt\Qt5.5.1\5.5\msvc2013_64\include\QtQml\qqmlengine.h:78: see declaration of 'QQmlContext'
    
    error: C2227: left of '->setContextProperty' must point to class/struct/union/generic type
    


  • Don't create a new context. Do it like this:

    QQmlApplicationEngine engine;
    ApplicationData data;
    engine.rootContext()->setContextProperty("appData", &data);
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));

    Another point here is that you need to set the context property before you load the qml file. Otherwise the loading of main.qml will fail because appData is still undefined.

    EDIT: And don't forget to #include <QQmlContext>


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.