PDA

View Full Version : QML and C++ interaction



cueMan
16th September 2010, 12:27
Hi,

I'm trying to get an access to my c++ class from within QML. The idea is to run a function in C++ side when I press a rectangle area in QML. Also sending a signal from qml and catching it in c++ is an option. But all the examples I've found with google don't seem to work. I.e:


QDeclarativeView view;
view.setSource(QUrl::fromLocalFile("main.qml"));
view.rootContext()->setContextProperty("stopwatch", new Stopwatch);
view.show();



import Qt 4.7

Rectangle {
width: 300
height: 300

MouseArea {
anchors.fill: parent
onClicked: {
if (stopwatch.isRunning())
stopwatch.stop()
else
stopwatch.start();
}
}
}

this would give me an error: TypeError: Result of expression 'stopwatch.start' [undefined] is not a function.

Also one example of connecting signal/slot:



QDeclarativeView view;
view.setSource(QUrl::fromLocalFile("main.qml"));
QObject *rootObject = dynamic_cast<QObject*>(view.rootObject());
QObject::connect(rootObject, SIGNAL(someqmlfunc()), &this, SLOT(somecpluplusfunc()));


but conversion from QGraphicsObject to QObject is not possible.

Is there some working way to call a c++ function from within qml at the moment?:confused:

cueMan
16th September 2010, 13:21
Ah, forgot to mark the function I wish to run in C++ with Q_INVOKABLE. Now works.

technoViking
10th November 2010, 19:07
Hi,

I'm having the same issue, can you post how you got it working? the C++ function you just have to surround with Q_+INVOKABLE?

WHat if you want to send a SIGNAL from QML that has data the user entered (from QML). to a C++ slot that will process that data.

cueMan
11th November 2010, 07:30
Haven't yet needed a signal slot mechanism between QML and Qt but here's how you can call C++ code from QML:

First you need your class:



#include <QObject>

class MyClass : public QObject
{
Q_OBJECT
public:
explicit MyClass(QObject *parent = 0);

Q_INVOKABLE void doThisAndThat(QString myString);
Q_INVOKABLE QString getThisAndThat();

signals:

public slots:

private:

QString localThisAndThat;
};


And you can create the implementation as you wish, no need to use the Q_INVOKABLE on the implementation side, though.

The you need to introduce this class to QML like this:



QDeclarativeView::rootContext()->setContextProperty("qmlReferenceName", myClass);


So you just give a string of your choice to qmlReferenceName, and pass your class on myClass. After this, you have this class as a global scope variable within your QML code:



Rectangle {
MouseArea {
anchors.fill: parent
onClicked: { qmlReferenceName.doThisAndThat("It works!") }
}

Text {
text: qmlReferenceName.getThisAndThat()

}
}