C++ access to QML component properties without creating component instances - c++

Consider the following QML example component defined in Test.qml
Item {
readonly property string name: "Test Component"
}
and I'm loading the component from C++
QQmlComponent comp(&engine, QUrl("file:/path/to/Test.qml"));
Is there any way to access the read only property name without creating an instance by calling comp.create(...)? I'm asking this because I want to use QML components to realize dynamic plugins. Each plugin should represent a project dependent interface. These "plugin" QML Files will be contained in a single folder and should be presented as a listing of the plugin/component names. The user should than be able to select which one of the plugins should be used (and instantiated by the application).
Since each "plugin" will also affect how the underlying C++ model is built and only one "plugin" should be instantiated at the same time, creating an instance of each just to get the name would introduce a significant overhead which I'm trying to avoid.
Unfortunately the property(...) method of QQmlComponent only refers to the component object but not to the properties of the underlying QML component. Is there any way to read default/read only properties without creating an instance?
Suggestions for alternative solutions are welcome as well.

Related

Qt QWidget multiple instances

We are multiple people working on one Qt app. I for one am implementing a library, which will be instanciated in multiple other parts of the app. This library has a display class+form along with it.
Until now I had simply created one single instance of the library, running on a dummy, and passed debug data to one instance of the display+form, and worked like that.
But now that core debugging is finished, goal is to have everything instantiable - not just the core library code, but also the form itself, and embed that form into other displays. Each caller/user would be reponsible for passing output data of the core library instance they are using to an instance of the form. Each instance of the form would separately display the information generated by a specific library instance, possibly with different display options - they are all independent.
Similarly, it is possible to enter values in my display. Goal is to be able to enter different values in different displays instantiated accross the app, and sending those to specific instances (caller's responsiblity).
Question is of course : how to do that ? Internet talks about promoting, but I still don't see anywhere in Qt Designer where to include so-called promoted objects in other objects.
TL;DR : : I want some existing form to appear in the menu on the left in Qt Designer to be able to instantiate it multiple times in other forms. How to do this ?
Thanks in advance for the help !
Charles
You can promote any QWidget to your control from within Qt Designer. Add a QWidget, right-click and promote.
Ideally, you should create a designer plugin for your control, make the relevant properties designable, and build the plugin as well as the library. That way you'll be able to drag your control from the palette, and it will behave like the real thing.
Qt QWidget multiple instances
You answered yourself. Qt Creator: "File->New->Qt->Qt Designer Form Class" with QWidget as a base class will suit you. Then you can promote a simple QWidget in the UI into this custom widget, to create an instance. Each instance will manage its own UI.

How to create a browser for system drives, folders and files

I want to create as the following:
Unfortunately, Qt does not supported ready widget for that.
Is there is a plugin or any way to do that?
Use QFileSystemModel on a QTreeView. If you look at the first of those two links, it actually contains example code doing exactly that.
would personally suggest not use QWidgets for this task if you can avoid it. Instead, try to utilize the new shiny QML way of building Qt UI. It might be only my personal opition, but QTreeView has several flaws in my opinion.
QML
Here you can find a simple example how it is done with QML these days. It is using the FolderListModel from Qt.labs.folderlistmodel 2.1.
FolderListModel provides access to information about the contents of a folder in the local file system, exposing a list of files to views and other data components.
Note: This type is made available by importing the Qt.labs.folderlistmodel module. Elements in the Qt.labs module are not guaranteed to remain compatible in future versions.
import Qt.labs.folderlistmodel 2.1
The folder property specifies the folder to access. Information about the files and directories in the folder is supplied via the model's interface.
C++ and QWidgets
Should you insist on doing in C++ with the old QWidget set, your choice is probably to use QTreeView as it is a tree view after all and then combine that with QFileSystemModel.
The code would be something like this:
QFileSystemModel *model = new QFileSystemModel;
model->setRootPath(QDir::currentPath());
QTreeView *tree = new QTreeView(splitter);
tree->setModel(model);
tree->setRootIndex(model->index(QDir::currentPath()));

Qt Editing Custom Data Structures

I am trying to utilize the Model/View architecture to accomplish my goal but I am unsure as to whether this is the proper tool to use for this task.
I have a Material System I have been using, which I more recently have created an editor for using Qt, it uses a QGraphicsView to display items which are interconnected to form a final fragment shader code, this works extremely well however, I am having difficulties finding a way to display these custom data structures without hand coding widgets for each type of item.
These custom data structures are simply classes with members which I wish to modify using an interface depending on each members type. For instance if the item is a Value which in my material system represents a single variable, like a texture, I would like to be able to have 2 editable areas, one for the texture's path on disk, and one for the name of the variable.
What is the best approach for interpreting custom structures like this and creating widgets based on their type, and then mapping those widgets to edit/display them. All the google searching I found led me to the Model/View architecture however it seems this is more made for things like SQL databases and XML files.
class Value
{
std::string m_strType, m_strName, m_strValue, m_strLocation;
};
It sounds like you're looking for something like the Property Browser Framework. In short, you'll make all of the members you want to edit properties, and then use the property browser framework to create a model that you can then attach a view to.

Add meta-data to a Qt property

I'm developing an application which displays items on a QGraphicsScene. These
items have properties, which I would like to display in a tree-view, if the
item is selected. If possible, I would like to stick with the property system
implemented by QObject. However, this does not fit all my needs because I need
to store some meta-data along the properties, e.g.
a category used for grouping (e.g. "System properties" and "User properties")
a tooltip text which is shown when the mouse hovers over the property in
the tree-view.
Inspired by Qt Property Browser and by Qt's object framework, I have thought to
implement the following system:
All items in the scene are derived from PropertyItem (which itself inherits
QGraphicsItem or QGraphicsObject). It contains
the logic to get and set the value of a property.
Every class derived from PropertyItem has a static MetaPropertyItem.
A MetaPropertyItem holds instances of the class MetaProperty in order
to store meta-data about the properties of such as the category, the
tooltip string and the type of the property.
Whenever an item is selected in the scene, instances of the Property class
are created for every MetaProperty from the associated MetaPropertyItem.
These properties are then shown in the tree-view and deleted when the item
is deselected.
The more I think about this design, the more I get the feeling that I'm doing
something wrong. It seems that I'm just duplicating what is already part of Qt:
PropertyItem <--> QObject
MetaPropertyItem <--> QMetaObject
MetaProperty <--> QMetaProperty
Property <--> needs to be implemented
I also found this bug ticket, which proposes to add meta-data to a Qt property.
Unfortunately, it did not get any attention so far.
Looking for alternatives, I also stumbled upon QMetaPropertyBuilder which
will (probably?) be part of Qt 5. Unfortunately, documentation about this class is sparse
and what I understood from reading the sources it would not solve my problem.
Thus, my question: Is there actually a better way to achieve what I'm
looking for without re-implementing another Qt framework?

EMF: Restricting choices to predefined values

I am using EMF to allow users to create instances of a particular type of model.
An instance of a model can have 0-* Things but I'd like to be able to predefine the available Things that the user can add to the instance so that they can't just create their own.
How would I go about creating the Things using the ecore model?
If a Thing was just a String then it would be fine - I could use Enums. But a Thing is a type of it's own and consists of other stuff (like a name, version etc.) and I don't know how to give a predefined set of these to the user to choose.
Any ideas?
You have the possibility to use constraints or *EOperation*s.
For a better usability you should use a own dialog implementation. An example of a own implementation with given choices you can find here:
How can I control which instances are available as choices when editing a property in the properties view?
You should also implement a own property source to support the properties editor:
Recipe: Create your own property editor in a generated application