Q_INVOKABLE oder wie kann ich Qt Funktionen in Qml benutzen?

Wir möchten in unserem Beispiel die Qt Funktion currentDateTime() in unserem Qml File benutzen um die aktuelle Zeit anzuzeigen.

Dazu fügen wir in unser myclass.h File die Beschreibung Q_INVOKABLE ein, was soviel heist wie die Funktion in Qml aufrufbar machen.

class MyClass : public QObject
{
    Q_OBJECT 
public:
    MyClass();
    ~MyClass();

    Q_INVOKABLE QDateTime getCurrentDateTime() //<--- unser Name für die in qml Aufrufbare Funktion 
     const {
        return  QDateTime::currentDateTime(); //Eigentliche Qt-Funktion
     }

signals:
    void setlabeltext(QString text);
public slots:
    void cppSlot(QString msg);
};

Jetzt müssen wir nur noch die Funktion irgendwie in unserem Qml file Aufrufen,

doch zuerst fügen wir in unser main.qml main_window über den Designer ein Rechteck und ein neues Label für Datum und Uhrzeit ein.

datum_uhrzeit

Diesen Label Text wollen wir nun jede Sekunde aktualisieren dazu verwenden wir die Vorher gelernte Möglichkeit C++ Signale mit Qml zu verbinden. (Den TextNamen text1 ändern wir noch auf datumzeit.)
Anschließend erstellen wir uns einen Timer und ein Signal sowie einen Slot in unserer myclass.h

#include <QObject>
#include <QDateTime>
#include <QDebug>
#include <QTimer>

class MyClass : public QObject
{
    Q_OBJECT

public:
    MyClass();
    ~MyClass();
    QTimer * SecondsTimer;
    Q_INVOKABLE QDateTime getCurrentDateTime()
     const {
        return  QDateTime::currentDateTime();
     }
signals:
    void setlabeltext(QString text);
    void emit_timer_second();

public slots:
    void cppSlot(QString msg);
    void emit_timer();
};

Unsere main.cpp erweitern wir um den Slot emit_timer() und füllen den Konstruktor MyClass mit etwas Leben das einen Timer erzeugt,verbindet und startet.

#include <QtGui/QGuiApplication>
#include "qtquick2applicationviewer.h"
#include "myclass.h"
#include <QQmlContext>
#include <QDateTime>
#include <QtCore>
#include <QDebug>
#include <QQuickItem>

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);
    QtQuick2ApplicationViewer viewer;

    MyClass data;
    viewer.rootContext()->setContextProperty("myclassData", &data);
    viewer.setMainQmlFile(QStringLiteral("qml/qtquick_uebung/main.qml"));

    //Verbindung von C++ über Signal Slots nach QML
    QString msg = "Dieser Text kommt von c++";
    emit data.setlabeltext(msg);

    //Verbindung von QML über Signal Slots nach C++
    QObject* viewerobject = viewer.rootObject();
    QObject::connect(viewerobject,SIGNAL(qmlSignal(QString)),&data,SLOT(cppSlot(QString)));

    MyClass(); //<-- hier wird myclass Aufgerufen
    viewer.showExpanded();
    return app.exec();
}

MyClass::MyClass()
{
    SecondsTimer = new QTimer(this);
    QObject::connect(SecondsTimer,SIGNAL(timeout()),this,SLOT(emit_timer()));
    SecondsTimer->start(1000);
}

MyClass::~MyClass()
{ 
}

void MyClass::cppSlot(QString msg)
{
  qDebug() << QString("Called the C++ slot with message:%1").arg(msg);
}

void MyClass::emit_timer()
{
    emit emit_timer_second();
}

Der Slot emit_timer() wird nun jede Sekunde aufgerufen und emittiert das Signal emit_timer_second(), dieses Signal fangen wir nun noch in Qml auf und setzen unsere Q_INVOKABLE Funktion ein um das DatumZeit Label auf die aktuelle Systemzeit zu setzen. Das Target für unser Signal ist immer noch myclassData daher fügen wir nun auch diesen Slot in Connections ein (Großbuchstabe beachten)

  Connections {
                   target: myclassData
                   onSetlabeltext: {
                     labeltext.text=text
                   }

                   onEmit_timer_second: {
                     datumzeit.text=Qt.formatDateTime(myclassData.getCurrentDateTime(),"dd.MM.yyyy:hh.mm.ss") //<--datumzeit ist unser neues label das wir nun setzen 
                   }
}

  Rectangle {           //die neuen Elemente Hellgruenes Rechteck und Text datumzeit
        id: rectangle1
        x: 0
        y: 0
        width: 360
        height: 27
        color: "#4dc635"

        Text {
            id: datumzeit
            x: 0
            y: 0
            width: 360
            height: 27
            text: Qt.formatDateTime(myclassData.getCurrentDateTime(),"dd.MM.yyyy:hh.mm.ss") //wenn wir von anfang an die aktuelle Zeit sehen wollen müssen wir den Text vorher setzen
            horizontalAlignment: Text.AlignRight
            font.pixelSize: 21
        }
    }

und voila wir bekommen das aktuelle Datum und aktuelle Zeit in unserem Label angezeigt

q_invokable

Hinterlasse einen Kommentar