Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Share an object between QML files

Tags:

c++

qt

qml

I'm new to coding in QML and I'm trying to write my first Sailfish OS app. For the backend I have created one C++ class. However, I want to instantiate one object of that C++ class and use it both in the Cover and the main Page (two separate QML files), so I can work with the same data, stored in that class. How do address that same object in the separate QML files?

like image 671
Ivan Bratoev Avatar asked Nov 06 '14 15:11

Ivan Bratoev


People also ask

How do you communicate between two QML files?

You don't communicate between qml files, the QML file is just a prototype, you communicate between the object instances. There are other ways to make a connection, however, connections happen between object instances, not qml files.

What are connections in QML?

A Connections object creates a connection to a QML signal. When connecting to signals in QML, the usual way is to create an "on<Signal>" handler that reacts when a signal is received, like this: MouseArea { onClicked: (mouse)=> { foo(mouse) } }

What is property alias in QML?

Unlike an ordinary property definition, which allocates a new, unique storage space for the property, a property alias connects the newly declared property (called the aliasing property) as a direct reference to an existing property (the aliased property).

How connect C++ to QML?

All QML signals are automatically available to C++, and can be connected to using QObject::connect() like any ordinary Qt C++ signal. In return, any C++ signal can be received by a QML object using signal handlers.


1 Answers

You can make the object available in the QtQuick context:

class MySharedObject : public QObject {
    Q_OBJECT
public:
    MySharedObject(QObject * p = 0) : QObject(p) {}
public slots:
    QString mySharedSlot() { return "blablabla"; }
};

in main.cpp

MySharedObject obj;    
view.rootContext()->setContextProperty("sharedObject", &obj);

and from anywhere in QML:

console.log(sharedObject.mySharedSlot())

If you don't want to have it "global" in QML, you can go about a little to encapsulate it, just create another QObject derived class, register it to instantiate in QML and have a property in it that returns a pointer to that object instance, this way it will be available only where you instantiate the "accessor" QML object.

class SharedObjAccessor : public QObject {
    Q_OBJECT
    Q_PROPERTY(MySharedObject * sharedObject READ sharedObject)

public:
    SharedObjAccessor(QObject * p = 0) : QObject(p) {}
    MySharedObject * sharedObject() { return _obj; }
    static void setSharedObject(MySharedObject * obj) { _obj = obj; }
private:
    static MySharedObject * _obj; // remember to init in the cpp file
};

in main.cpp

MySharedObject obj;
qRegisterMetaType<MySharedObject*>();

SharedObjAccessor::setSharedObject(&obj);
qmlRegisterType<SharedObjAccessor>("Test", 1, 0, "SharedObjAccessor");

and in QML

import Test 1.0
...
SharedObjAccessor {
        id: acc
}
...
console.log(acc.sharedObject.mySharedSlot())
like image 52
dtech Avatar answered Sep 19 '22 01:09

dtech