Solved Qt Quick Designer: C++ registered item is not a type
-
Hi,
I have a project with custom QAbstractListModel and registered in QML. Then I edit a QML file in Qt Quick Designer, if this item is referred, it won't be able to render the content correctly. It will complain "JsonListModel is not a type" (JsonListModel is the registration name).
How can I let Qt Quick Designer recognize a C++ item? In fact, I don't really need Qt Quick Designer to understand how the JsonListModel works. Because it is not directly used with the editing item. It is just imported by another item.
I have tried to create a qmltypes file but it don't work. Still complains JsonListModel is not a type.
Any advise / suggestion to solve this problem?
That is the hierarchy of my application:
MyItemForm.ui.qml ^ | + MyItem.qml <---- MyViewForm.ui.qml (Editing item) | | v Store.qml <singleton> + listModel: JsonListModel
MyItem.qml
refer to a singleton object to obtain data. And the singleton object contains my own JsonListModel, but in fact it is not needed by MyItem.qml.Now I want to edit
MyViewForm.ui.qml
by Qt Quick Designer, usually it should renderMyItemForm.ui.qml
correctly. But due to the error of "JsonListModel is not a type", it was failed. -
The classical solution in the past for this problem was to create a plugin for JsonListModel and install this plugin into your Qt.
Then you can enable building the QML emulation layer for your specific Qt in the options of Qt Creator for Qt Quick and it does work.In Qt Creator 4.2 we added two additional features.
-
If we find qmlRegisterType calls in the current project we define a "mockup" type so that component using that type can
be instantiated. This approach should work for your JsonListModel . -
We parse a new (currently still undocumented) qmake QML_DESIGNER_IMPORT_PATH. You can use this variable to define a QML plugin path just for the designer to mockup types like JsonListModel manually. This is especially useful if your items are visible or have visible effects. What I sometimes did in the past was using a .qmlproject project for designing that also contained a couple of mockup imports.
Generally what helps is using singletons, but JsonListModel is a bad example, because you most likely have several JsonListModels with different properties. But in many applications there is a definite number of models and objects from the C++ backend that can be exposed as singletons to QML. This has the advantage that singletons only show up on the right side of bindings and do not trigger fatal errors in components.
-
-
@Thomas-Hartmann Thanks for your reply. The new features in Qt 4.2 are cool. Do you know when is the expected release time for 4.2?
I am interested with your solution of mockup imports. (Create a C++ plugin for non-shared code is a bit odd). Before 4.2 is ready, I think I could make it by adding the path to QML_IMPORT_PATH.
-
Qt Creator 4.2 is planned to be released in December. But the current snapshots are already pretty stable, so please give them a try.
Qt Creator 4.1 ignores QML_IMPORT_PATH for the designer unless you build your own QML emulation layer (qml2puppet), but Qt Creator 4.2 will try to load plugins in any case.
Using QML_IMPORT_PATH to mockup imports is fine, but might confuse the code model in some cases. This is the reason why we added QML_DESIGNER_IMPORT_PATH.
While creating a plugin is some extra work it the cleanest solution and the only way to get real custom QQuickItems working in the designer.
-
hmm... I have tried different setup but still can't get it work.
Qt Creator 4.1 + QML_IMPORT_PATH + QML emulation layer + mockup folder.
It will still complain "JsonListModel" is not a type. Moreover, everytime I press "Run Checks" the result could be different. Sometimes it will complains a custom QML item in same folder is "Unknown type"
Qt Creator 4.2 Beta 565, No mockup folder
It will complain "Can not assign to non-existent property "fields".
Qt Creator 4.2 Beta 565, Mockup folder + QML_DESIGNER_IMPORT_PATH
It will complain "Can not assign to non-existent property "fields". Sometime it may show "QtMultiMedia 5.0 is not installed" (It is already installed)
(The mockup of JsonListModel.qml already contains the fields property)
-
It is rather strange. If I copy the C++ class and mockup file into a new project. That would works even in Qt Creator 4.1.
-
I added a manual test to Qt Creator that you can use as an example: https://codereview.qt-project.org/#/c/174798/
-
@Thomas-Hartmann Thank you!
By the way, I just find out what is wrong with it . I have two mockup folders in my project. The first one contains qmldir and qmltypes file that created before my first post. Then I create second mockup folder with qmldir and qml files according to your solution. Since the first one are purely experimental and saved in a path ignored by git. I have forgotten to remove it. And Qt Quick Designer ignore the second folder (due to the path order in QML_IMPORT_PATH). That cause the problem.
-
@Thomas-Hartmann By the way, I have a question not related to the origianl problem.
"If we find qmlRegisterType calls in the current project we define a "mockup" type so that component using that type can be instantiated. "
Will the mockup data be able to export to a file? I am writing a tool to work with Qt Creator. Probably it need this information.
-
We create those mockup types internally, so no files are created. This just stops the engine from reporting errors.
You could also use QML_DESIGNER_IMPORT_PATH to define an import path for manual mockup files.
Before we create the mockup we check, if the type is already available and only create the mockup if it is not.