1

I have created two QML plugins with C++. Plugin A represents some specific UI item types and plugin B represents own "storage" singleton QML item type. The original motivation was to create QML storage singleton and use it through the most of QML UI code. Now I also want a direct interaction between A and B meaning they interact with each other just in C++ code bypassing QML. Only A needs to know about B, not the other way around. How can I achieve that?

No rootObject->findChild type of solution needed. The question is somewhat similar to Accessing QML objects from C++ except I need to be able to instantiate the object from QML PlugIn dynamic library in C++. I see the on-surface solution with dynamic library used by both QML and C++ code. But it is a bit more complicated: it has to be just one instance of code with data. Also there is probably a way to somehow "cast" the instance QML of plugin object to normal Qt plugin and then call whatever I want from it.

Alexander V
  • 8,351
  • 4
  • 38
  • 47

1 Answers1

1

I think this should also work for Plugins and not only for registered types. I can't try it right now, I will remove this line once I tried it out later that day:

Each QML Singleton, defined in C++ needs to have a static method with the signature:

static QObject* someName(QQmlEngine *, QJSEngine *);

that returns a pointer to the single instance of this class.

I think usually you don't need the QQmlEngine or QJSEngine to make it work, so you can easily implement the full Singleton-Pattern by adding a second static method:

static QObject* instance();

which returns exactly the same. You might alternatively have a

static MySingletonObject* instance();

so you don't need to cast afterwards.

Now you can just import your class, and you will have access to the very same instance, by calling this static method.


If above does not work, you might do it the hacky way:

You can alternatively use your root node and set a property:

property QtObject mySingleton: MySingleton

Then you can use findChild to grab your root node and read the very same property. To be able to do this you might need to access something of the singleton before, as otherwise the instance might be missing.

property Item singl: MySingleton

Component.onCompleted: {
    // MySingleton.color = 'green' // If this line is commented out, it will fail for me for a QML-defined Singleton at least.
    singl.color = 'red'
}

This solution works for me for QML-defined qmldir-registered singletons, as well as C++-defined and qmlRegisterSingleton(...)-registered singletons. With QML-defined singletons you might need access the singleton once, before you can assign it. I don't know the internal reasons for that.

  • Your approach is logical but I cannot resolve GCC run-time error `undefined symbol _ZNK9MyQmlType10metaObjectEv` yet. So, unless the plug-in dynamic library was already loaded the way plugin loaded it seems there is no way to do so. `qmlRegister*` functions cannot register the type without implementation of type type being accessible. – Alexander V Sep 22 '17 at 19:25
  • Which approach where you taking? Could you create a MCVE? – derM - not here for BOT dreams Sep 23 '17 at 10:46
  • I decided to use https://stackoverflow.com/questions/28112038/qml-plugin-load-from-c for a workaround which I didn't really want but at least that works. – Alexander V Sep 24 '17 at 04:35