How to access a nested QML object from C++? - c++

Here is a reproducible example:
main.qml
import QtQuick 2.0
Item {
id : root
width: 360
height: 360
Text {
id : t1
text: qsTr("Hello World")
property int someNumber: 1000
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
main.cpp
#include <QtGui/QGuiApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQmlProperty>
#include <QDebug>
#include "qtquick2applicationviewer.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/untitled/main.qml"));
viewer.showExpanded();
QQmlEngine engine;
QQmlComponent component(&engine, "qml/untitled/main.qml");
QObject *object = component.create();
qDebug() << "Property value:" << QQmlProperty::read(object, "root.t1.someNumber").toInt();
return app.exec();
}
I wish to access the property somenumber of the text of the QML Item.
The above method isn't producing the desired result.
How to do it?

You have two ways (at least) to accomplish this depending on your personal preference.
QML code extension
You can add a property alias to the root item as follows:
import QtQuick 2.0
Item {
id : root
width: 360
height: 360
property alias mySomeNumber: t1.someNumber // This is the addition
Text {
id : t1
text: qsTr("Hello World")
property int someNumber: 1000
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
C++ code extension
Since the QML items are QObject, you can look for the children explicitly as well, just as you would do it in a C++ QObject hierarchy. The code would be something like this:
#include <QtGui/QGuiApplication>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QQmlProperty>
#include <QDebug>
#include "qtquick2applicationviewer.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/untitled/main.qml"));
viewer.showExpanded();
QQmlEngine engine;
QQmlComponent component(&engine, "qml/untitled/main.qml");
QObject *object = component.create();
// This line is added
QObject *childObject = object->findChild<QObject*>("SomeNumberText");
// The following line is modified respectively
qDebug() << "Property value:" << QQmlProperty::read(childObject, "someNumber").toInt();
return app.exec();
}
However, this means you will need to add the objectName: "SomeNumberText" line to your Text child item in the qml file.

Here you can find a recursive method looking for a QML item by objectName and starting at QQmlApplicationEngine::rootObjects():
////
static QQuickItem* FindItemByName(QList<QObject*> nodes, const QString& name)
{
for(int i = 0; i < nodes.size(); i++){
// search for node
if (nodes.at(i) && nodes.at(i)->objectName() == name){
return dynamic_cast<QQuickItem*>(nodes.at(i));
}
// search in children
else if (nodes.at(i) && nodes.at(i)->children().size() > 0){
QQuickItem* item = FindItemByName(nodes.at(i)->children(), name);
if (item)
return item;
}
}
// not found
return NULL;
}
///
static QQuickItem* FindItemByName(QQmlApplicationEngine* engine, const QString& name)
{
return FindItemByName(engine->rootObjects(), name);
}

What is the use case for this? It might be better to just treat the [text, someNumber] struct or object as the model. Then you only need to find the model object. Or you could create the model object on the C++ side and set it in the QML context. You could access the model and its nested properties in QML:
Text {
text: model.text
property int someNumber: model.someNumber
}

Related

Why access C++ function from QML failed if the C++ class is derived from QAbstractItemModel [duplicate]

I'm trying to make a little program with Qt. I have a main.cpp with the following code:
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
return app->exec();
}
int reken_tijden_uit(){
return true;
}
and I have a .qml file:
import QtQuick 1.1
Rectangle {
width: 360
height: 360
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
Now, when I click on the MouseArea, the program quits. What I want is that it calls the function reken_tijden_uit in the main.cpp file.
I've googled a lot, and searched on this site to. I've found a couple of answers, but I didn't get one working.
So what code do I put where so I can call the function reken_tijden_uit in C++?
Thanks in advance.
The header file looks like this:
#ifndef EIGEN_FUNCTION_HEADER_H
#define EIGEN_FUNCTION_HEADER_H
class MyObject : public QObject{
Q_OBJECT
public:
explicit MyObject (QObject* parent = 0) : QObject(parent) {}
Q_INVOKABLE int reken_tijden_uit(){
return 1;
}
};
#endif // EIGEN_FUNCTION_HEADER_H
main.cpp:
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include "eigen_function_header.h"
QScopedPointer<QApplication> app(createApplication(argc, argv));
qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject");
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
return app->exec();
}
and the QML file:
import QtQuick 1.1
import com.myself 1.0
Rectangle {
width: 360
height: 360
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MyObject {
id: myobject
}
MouseArea {
anchors.fill: parent
onClicked: {
myobject.reken_tijden_uit()
}
}
}
And the errors are as follow:
D:\*\main.cpp:6: error: 'argc' was not declared in this scope
D:\*\main.cpp:6: error: 'argv' was not declared in this scope
D:\*\main.cpp:8: error: expected constructor, destructor, or type conversion before '<' token
So what did I do wrong?
For any C++ code to be called from QML, it must reside inside a QObject.
What you need to do is create a QObject descended class with your function, register it to QML, instantiate it in your QML and call the function.
Note also that you have to mark your function with Q_INVOKABLE.
Code:
#ifndef EIGEN_FUNCTION_HEADER_H
#define EIGEN_FUNCTION_HEADER_H
#include <QObject>
class MyObject : public QObject{
Q_OBJECT
public:
explicit MyObject (QObject* parent = 0) : QObject(parent) {}
Q_INVOKABLE int reken_tijden_uit(){
return 1;
}
};
#endif // EIGEN_FUNCTION_HEADER_H
main.cpp:
#include <QtGui/QApplication>
#include <QtDeclarative>
#include "qmlapplicationviewer.h"
#include "eigen_function_header.h"
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject");
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
return app->exec();
}
QML:
import QtQuick 1.1
import com.myself 1.0
Rectangle {
width: 360
height: 360
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MyObject {
id: myobject
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log(myobject.reken_tijden_uit())
}
}
}
As an alternative to qmlRegisterType() in main.cpp, you can also use context properties to make QObject variables available in QML. (In case you don't require to create different instances of your object with later QML).
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
// add single instance of your object to the QML context as a property
// the object will be available in QML with name "myObject"
MyObject* myObject = new MyObject();
viewer.engine()->rootContext()->setContextProperty("myObject", myObject);
return app->exec();
}
In QML, you can then access the object from anywhere in your code with the given name specified in main.cpp. No additional declarations required:
MouseArea {
anchors.fill: parent
onClicked: {
myObject.reken_tijden_uit()
}
}
You can find more information on QML<->C++ communication possibilities here: https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml

Right QML <-> C++ declarative approach

I have some data structure updated in c++ layer. I have to display it in qml and save changes from qml layer to c++ structures. I hope there is a declarative approach to do it but I in desperate to find it.
Here is the part of code:
C++ header:
#ifndef NODEINFO_H
#define NODEINFO_H
#include <QObject>
#include <QString>
class NodeInfo : public QObject {
Q_OBJECT
Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
public:
NodeInfo(QObject *parent = 0);
virtual ~NodeInfo() {}
const QString& label() const;
void setLabel(const QString& val);
signals:
void labelChanged();
private:
QString d_label;
};
#endif // NODEINFO_H
C++ body:
#include "nodeinfo.h"
#include <QDebug>
NodeInfo::NodeInfo(QObject *parent) : QObject(parent), d_label("Test string") {
}
const QString &NodeInfo::label() const {
qDebug() << "NodeInfo::label: getter";
return d_label;
}
void NodeInfo::setLabel(const QString &val) {
qDebug() << "NodeInfo::label: setter - " << val;
d_label = val;
emit labelChanged();
}
main.cpp
#include <QGuiApplication>
#include <QDebug>
#include <QQmlContext>
#include <QQuickView>
#include <QQmlApplicationEngine>
#include "nodeinfo.h"
int main(int argc, char *argv[]) {
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
// qmlRegisterType<NodeInfo>("NodeInfo", 1, 0, "NodeInfo");
NodeInfo nodeDescr;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("nodeData", &nodeDescr);
const QUrl url(QStringLiteral("qrc:/main.qml"));
engine.load(url);
QObject *root = engine.rootObjects().value(0);
if (QWindow *window = qobject_cast<QWindow *>(root))
window->show();
else
return -1;
return app.exec();
}
Qml code:
import QtQuick 2.15
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12
ApplicationWindow {
id: root
width: 360
height: 520
visible: true
// property alias a_label: nodeData.label
Column {
anchors.fill: parent
TextInput {
id: simpleTxt
text: nodeData.label
}
Text {
id: txt
text: nodeData.label
}
Button {
text: "writeProp"
onClicked: nodeData.label = simpleTxt.text
}
// Binding {
// target: nodeData
// property: "label"
// value: simpleTxt.text
// }
}
}
So when I'm editing text in TextInput it should automatically set property in c++ code but it do not. Only if I press button.
There is the Binding way as you see in comments and it works but I it's not a true way I hope.
Let's imagine if I have 15-30 or more data fields in my c++ structure and it's full rubbish if I must do 30 Bindings such way or if I need to write signal/slot on each data field and connect them.
But what is right way?
Any ideas appreciated
A simpler solution is to assign the signal associated to the property text:
Text {
id: txt
text: nodeData.label
onTextChanged: {
if(nodeData.label != simpleTxt.text)
nodeData.label = simpleTxt.text
}
}
text: nodeData.label sets binding nodeData.label --> text (one direction). I.e. text is updated whenever nodeData.label is changed. When the user types some text in the field, this binding is destroyed.
So if you want to update nodeData.label when the user changes text, you need to use onTextChaged event.
Text {
onTextChanged: nodeData.label = text
}
One more note: you need to check if the property is really changed before emitting the appropriate changed signal. So the code should be something like this:
void NodeInfo::setLabel(const QString &val) {
qDebug() << "NodeInfo::label: setter - " << val;
if (d_label != val)
{
d_label = val;
emit labelChanged();
}
}
This will prevent your code from endless binding loops.

How to set QML properties from C++

I'm trying to do a simple task as changing a property (text: ) of some QML object from C++ yet I'm failing miserably. Any help appreciated.
I'm not getting any errors, the window shows up, just the text property doesn't change as (at least I think) it should.
Is even anything I'm NOT doing wrong here?!!
What I was trying is this:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QQuickItem>
#include <QQmlEngine>
#include <QQmlComponent>
#include <QString>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
QQmlComponent component(&engine, QUrl::fromLocalFile("main.qml"));
QObject *object = component.create();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QString thisString = "Dr. Perry Cox";
object->setProperty("text", thisString); //<--- tried instead of thisString putting "Dr. ..." but nope.
delete object;
return app.exec();
}
main.qml
import QtQuick 2.2
import QtQuick.Window 2.1
Window {
visible: true
width: 360
height: 360
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
Text {
id: whot
text: ""
anchors.centerIn: parent
font.pixelSize: 20
color: "green"
}
}
When you call QObject *object = component.create(); you get access to the root context, which is the Window component and its properties.
To get access to Text properties, you can create property alias like this:
Window {
property alias text: whot.text
...
Text {
id: whot
text: ""
...
}
}
That will give you access to whot's text property from within the Window's context.
There is another slightly more round-about way. Assign objectName property instead of id (or both if you still need id) to whot:
Text {
id: whot // <--- optional
objectName: "whot" // <--- required
text: ""
...
}
Now you can do this in code:
QObject *whot = object->findChild<QObject*>("whot");
if (whot)
whot->setProperty("text", thisString);
On a side note: I don't think you are supposed to delete the object until after calling app.exec(). Otherwise, it will ... well, be deleted. :)
#include <QQmlContext>
#include <qquickview.h>
#include <qdir.h>
QQmlApplicationEngine engine;
QString root = QCoreApplication::applicationDirPath();
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
QObject *topLevel = engine.rootObjects().value(0);
QQuickWindow *window = qobject_cast<QQuickWindow*>(topLevel);
window->setProperty("root", root);
for qml
ApplicationWindow {
property string root
onRootChanged: {
console.log("root : "+ root);
}
}
For QML properties you should use QQmlProperty instead:
QQmlProperty::write(whot, "text", thisString);

How to connect QQuickitem with Qml Object?

I am trying to make a simple program that allow user to connect to the specific websites via clicking the image.
Here is my code:
account.h:
#ifndef ACCOUNTS_H
#define ACCOUNTS_H
#include <QObject>
#include <QUrl>
#include <QDesktopServices>
class accounts : public QObject
{
Q_OBJECT
public:
explicit accounts(QObject* parent = 0) : QObject(parent){}
public slots:
void gmailOpen(const QString &msg)
{
QUrl gmailUrl(msg);
QDesktopServices::openUrl(gmailUrl);
}
};
#endif // ACCOUNTS_H
main.cpp:
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickView>
#include <QtQml>
#include "accounts.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView *view = new QQuickView;
QObject *gmail = view->rootObject().findChild<QObject*>("gmailLink");
accounts *gmailAccount = new accounts;
QObject::connect(gmail, SIGNAL(gmailSignal(QString)),gmailAccount,SLOT(gmailOpen(QString)));
view->setSource(QUrl::fromLocalFile("/Users/yudelin/Documents/MyCrazyProjects/Managers4ManyAccounts/main.qml"));
view->show();
return app.exec();
}
main.qml:
import QtQuick 2.0
Rectangle {
width: 360
height: 360
color: "silver"
Image {
id:gmailLink
objectName: "gmailLink"
width: 102
height: 199
fillMode: Image.PreserveAspectFit
source: "...." //the url is too long so I omit it.
anchors.centerIn: parent
signal gmaiSignal (string msg)
MouseArea {
anchors.fill: parent
onClicked:
gmailLink.gmailSignal("http://mail.google.com")
}
}
}
As you can see, I am trying to connect Qml Image with c++ object accounts.
So I use QObject *gmail = view->rootObject().findChild<QObject*>("gmailLink"); to fetch the qml object.
But it does not work. I guess it is suit for the older Qt version.
How could I fix this problem?
You want gmailOpen slot to be called on clicking on the Image. There are simpler and preferred ways of doing it other than doing this.
QObject *gmail = view->rootObject().findChild("gmailLink");
As #Kunal pointed out, you can use Qt.openUrlExternally(string).
If you want to open the Url by using QDesktopServices::openUrl from the gmailOpen slot, you can call the slot directly by setting the context property.
4, QObject *gmail = view->rootObject().findChild<QObject*>("gmailLink");... Here before setting the qml file, you are trying to get a reference for the gmailLink object. Its not created yet.
Following code explains my take on the problem
5a. accounts.h file
#ifndef ACCOUNTS_H
#define ACCOUNTS_H
#include <QObject>
#include <QUrl>
#include <QDesktopServices>
class accounts : public QObject
{
Q_OBJECT
public:
explicit accounts(QObject* parent = 0) : QObject(parent){}
public slots:
void gmailOpen(const QString &msg)
{
QUrl gmailUrl(msg);
QDesktopServices::openUrl(gmailUrl);
}
};
#endif // ACCOUNTS_H
5b. main.cpp file
#include <QtGui/QGuiApplication>
#include <QtQuick/QQuickView>
#include <QtQml>
#include "accounts.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
accounts *gmailAccount = new accounts;
QQuickView *view = new QQuickView;
view->engine()->rootContext()->setContextProperty("accounts",gmailAccount);
view->setSource(QUrl::fromLocalFile("qml/SO_OpenExternalLink/main.qml"));
view->show();
return app.exec();
}
5c. main.qml file
import QtQuick 2.1
import QtQuick.Dialogs 1.0
Rectangle {
width: 360
height: 360
color: "silver"
Image {
id:gmailLink
objectName: "gmailLink"
width: 102
height: 199
fillMode: Image.PreserveAspectFit
source: "http://upload.wikimedia.org/wikipedia/commons/4/41/Flag_of_India.svg"
anchors.centerIn: parent
MouseArea {
anchors.fill: parent
onClicked:Qt.openUrlExternally("http://mail.google.com")
}
}
Image{
id:secondImage
width:102
height:199
fillMode:Image.PreserveAspectFit
source: "http://upload.wikimedia.org/wikipedia/commons/5/55/Emblem_of_India.svg"
anchors.left:gmailLink.right
anchors.top: gmailLink.top
MouseArea {
anchors.fill: parent
onClicked:fileDialog.visible = true
}
}
FileDialog {
id: fileDialog
title: "Please choose a file"
nameFilters: [ "Image files (*.jpg *.png)", "All files (*)" ]
visible:false;
selectMultiple:false
onAccepted:secondImage.source = fileDialog.fileUrl
}
}
5d. You need to change the following from the above code
i. Image source
ii. QML file path in the main.cpp
iii. Possibly import QtQuick 2.0 if you don't have QtQuick 2.1 yet.
If you just want to open URL then you can use Qt.openUrlExternally(string) directly from QML. Here is documentation. No need to create a QObject for this.
And for your code. I don't see any method named gmailSignal.
You should be calling gmailOpen.
like
gmailLink.gmailOpen("http://mail.google.com")

Access C++ function from QML

I'm trying to make a little program with Qt. I have a main.cpp with the following code:
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
return app->exec();
}
int reken_tijden_uit(){
return true;
}
and I have a .qml file:
import QtQuick 1.1
Rectangle {
width: 360
height: 360
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
onClicked: {
Qt.quit();
}
}
}
Now, when I click on the MouseArea, the program quits. What I want is that it calls the function reken_tijden_uit in the main.cpp file.
I've googled a lot, and searched on this site to. I've found a couple of answers, but I didn't get one working.
So what code do I put where so I can call the function reken_tijden_uit in C++?
Thanks in advance.
The header file looks like this:
#ifndef EIGEN_FUNCTION_HEADER_H
#define EIGEN_FUNCTION_HEADER_H
class MyObject : public QObject{
Q_OBJECT
public:
explicit MyObject (QObject* parent = 0) : QObject(parent) {}
Q_INVOKABLE int reken_tijden_uit(){
return 1;
}
};
#endif // EIGEN_FUNCTION_HEADER_H
main.cpp:
#include <QtGui/QApplication>
#include "qmlapplicationviewer.h"
#include "eigen_function_header.h"
QScopedPointer<QApplication> app(createApplication(argc, argv));
qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject");
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
return app->exec();
}
and the QML file:
import QtQuick 1.1
import com.myself 1.0
Rectangle {
width: 360
height: 360
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MyObject {
id: myobject
}
MouseArea {
anchors.fill: parent
onClicked: {
myobject.reken_tijden_uit()
}
}
}
And the errors are as follow:
D:\*\main.cpp:6: error: 'argc' was not declared in this scope
D:\*\main.cpp:6: error: 'argv' was not declared in this scope
D:\*\main.cpp:8: error: expected constructor, destructor, or type conversion before '<' token
So what did I do wrong?
For any C++ code to be called from QML, it must reside inside a QObject.
What you need to do is create a QObject descended class with your function, register it to QML, instantiate it in your QML and call the function.
Note also that you have to mark your function with Q_INVOKABLE.
Code:
#ifndef EIGEN_FUNCTION_HEADER_H
#define EIGEN_FUNCTION_HEADER_H
#include <QObject>
class MyObject : public QObject{
Q_OBJECT
public:
explicit MyObject (QObject* parent = 0) : QObject(parent) {}
Q_INVOKABLE int reken_tijden_uit(){
return 1;
}
};
#endif // EIGEN_FUNCTION_HEADER_H
main.cpp:
#include <QtGui/QApplication>
#include <QtDeclarative>
#include "qmlapplicationviewer.h"
#include "eigen_function_header.h"
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
qmlRegisterType<MyObject>("com.myself", 1, 0, "MyObject");
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
return app->exec();
}
QML:
import QtQuick 1.1
import com.myself 1.0
Rectangle {
width: 360
height: 360
Text {
text: qsTr("Hello World")
anchors.centerIn: parent
}
MyObject {
id: myobject
}
MouseArea {
anchors.fill: parent
onClicked: {
console.log(myobject.reken_tijden_uit())
}
}
}
As an alternative to qmlRegisterType() in main.cpp, you can also use context properties to make QObject variables available in QML. (In case you don't require to create different instances of your object with later QML).
Q_DECL_EXPORT int main(int argc, char *argv[])
{
QScopedPointer<QApplication> app(createApplication(argc, argv));
QmlApplicationViewer viewer;
viewer.setOrientation(QmlApplicationViewer::ScreenOrientationAuto);
viewer.setMainQmlFile(QLatin1String("qml/tw_looptijden_berekenen/main.qml"));
viewer.showExpanded();
// add single instance of your object to the QML context as a property
// the object will be available in QML with name "myObject"
MyObject* myObject = new MyObject();
viewer.engine()->rootContext()->setContextProperty("myObject", myObject);
return app->exec();
}
In QML, you can then access the object from anywhere in your code with the given name specified in main.cpp. No additional declarations required:
MouseArea {
anchors.fill: parent
onClicked: {
myObject.reken_tijden_uit()
}
}
You can find more information on QML<->C++ communication possibilities here: https://v-play.net/cross-platform-development/how-to-expose-a-qt-cpp-class-with-signals-and-slots-to-qml