Nick Lehmann
Nick Lehmann

Reputation: 637

Invoke methods of QQuickItem (TextArea) in C++

Is it possible to invoke a method of a QQuickItem in C++.

My idea is make a program with a graphical UI created with Qml. I'd like to have a log on this UI. Now I placed a TextArea on it and add log entries via the append() method. It's very simple to use this method but I don't know how to do this in C++. Here is the start of my program. I did a workaround to solve this program via an extra "JavaScript" function but I'm not really pleased with that.

main.qml

import QtQuick 2.0
import QtQuick.Controls 1.0

Item {
    id: root
    width: 400
    height: 400

    signal requestMessage()

    function addLine() {
        log.append(addField.text.toString())
        addField.text = ""
    }

    function cMessage(msg) {
        log.append(msg)
    }


    TextArea {
        id: log
        x: 20
        y: 28
        objectName: "log"
        width: 340
        height: 200

        anchors.right: parent.right
        anchors.rightMargin: 20
        anchors.left: parent.left
        anchors.leftMargin: 20
    }

    TextField {
        id: addField
        x: 20
        y: 252
        height: 25

        anchors.right: addButton.left
        anchors.rightMargin: 10
        anchors.left: parent.left
        anchors.leftMargin: 20
    }

    Button {
        id: addButton
        x: 284
        y: 252
        width: 96
        height: 27

        text: "Hinzufügen"

        anchors.right: parent.right
        anchors.rightMargin: 20

        MouseArea {
            anchors.fill: parent
            onClicked: addLine()
        }
    }

    Button {
        id: bindingButton
        x: 239
        y: 290

        text: "Nachricht von C++"

        anchors.right: parent.right
        anchors.rightMargin: 20

        MouseArea {
            anchors.fill: parent
            onClicked: requestMessage()
        }
    }
}

main.cpp

#include <QGuiApplication>
#include <qtquick2applicationviewer.h>
#include <QQuickItem>
#include <QObject>
#include "myclass.h"

int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/Bindings/main.qml"));
QQuickItem *item = viewer.rootObject();

MyClass myClass;
myClass.setViewer(&viewer);
QObject::connect(item, SIGNAL(requestMessage()), &myClass, SLOT(treatMessage()));

viewer.show();
return a.exec();

}

And finally the myclass.h

#ifndef MYCLASS_H
#define MYCLASS_H

#include <QObject>
#include <QQuickItem>
#include <qtquick2applicationviewer.h>

class MyClass : public QObject
{
    Q_OBJECT
public:
    explicit MyClass(QObject *parent = 0);
    void setViewer(QtQuick2ApplicationViewer *newViewer) {
        this->viewer = newViewer;
    }

signals:

public slots:
    void treatMessage() {
        QQuickItem *root = viewer->rootObject();
        QVariant message = "hello from the other side";
        QMetaObject::invokeMethod(root, "cMessage", Q_ARG(QVariant, message));
    }

protected:
    QtQuick2ApplicationViewer * viewer = 0;
};

#endif // MYCLASS_H

So does anybody know a way to perform this task a little bit more elegant? Or could anybody tell me how to invoke the append() method?

Regards

Upvotes: 0

Views: 1870

Answers (1)

ksimons
ksimons

Reputation: 3826

You can absolutely invoke methods on a QML item from the QML side of things. See the docs here: http://qt-project.org/doc/qt-5.1/qtqml/qtqml-cppintegration-interactqmlfromcpp.htmls

You've got most of the pieces in place, you just need to find your actual TextArea by:

  1. Setting the objectName property on your TextArea to something like "log".
  2. Calling findChild(QStringLiteral("log")) on the rootObject() of your QQuickView. See: http://qt-project.org/doc/qt-5.1/qtqml/qtqml-cppintegration-interactqmlfromcpp.html#accessing-loaded-qml-objects-by-object-name
  3. Once you have a reference to that, you can use QMetaObject::invokeMethod on it to call the append method. See: http://qt-project.org/doc/qt-5.1/qtqml/qtqml-cppintegration-interactqmlfromcpp.html#invoking-qml-methods

Upvotes: 2

Related Questions