Tried a lot and find a solution, which seems to work, although it maybe can be improved.
QmlExtensionPlugin was in deed the right way to go:
http://doc.qt.io/qt-5/qtqml-qmlextensionplugins-example.html
Some additions to the tutorial:
If you want to have a module called "Test" then you qmldir file has to be in a Test folder. In you mainApplication you add the Path to this TestFolder (not to the qmldir) to the ImportPath.
app
src
import
Test
libtest.so
Test.qml
qmldir
main.cpp
If this is your folder structure, you would to in main.cpp
engine.addImportPath("Import");
your qmldir would look like this
module Test
CustomType 1.0 Test.qml
plugin test
You could import then Test 1.0 in your qml files and use CustomType.
Instead, you might want the software to detect plugins. So here is my solution to this, there are probably better ways to do this (for example if you want to display all plugins in a Grid or something like this and don't know, which plugins might be there or won't)
You need to have a consisten plugin structure. For example, name your Qml Component always Main.qml and put it in the first Folder (with your qmldir)
-> if you don't want to lose the ability to instantiate the Elements in qml by importing the module (as you probably don't want them all to be named Main), you can leave you Test.qml file just as it is and create a wrapper for this called Main.qml
import QtQuick 2.10
Item {
id: root
property alias someProperty: test.someProperty
....
Test {
id: test
anchors.fill: parent
}
}
Suppose all your plugins are in a folder called import, you could list all Folders (=Plugin folder) in the import Directory, iterate over them and get all the filePaths of Main.qml
QDir pluginsDir {"Import"};
for(QString folderName : pluginsDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot)) {
if(pluginsDir.exists(folderName)) {
pluginsDir.cd(folderName);
if(pluginsDir.exists("Main.qml")) {
qDebug() << pluginsDir.absoluteFilePath("Main.qml");
}
pluginsDir.cdUp();
}
}
Make all the FilePaths available to qml, for example by creating a custom C++ QStringList model and import it in qml. In qml you can use those strings to instantiate the Elements with JavaScript.
See:
http://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html
Unfortunately, you cannot add plugins at runtime. You will need to restart the application, so it searches again for all plugins. You could solve this by creating a daemon watching the plugin directory and sending signals if there is a change.
If you have another (better/simpler) solution than this, feel free to add it here.