Please nominate your Qt Champions for 2021!

[SOLVED] Best appraoch for this QML problem

  • Hi All,

    Situation: Our scenario has many pages, each page is distinct and has a layout (vertical/horizontal), and many UI elements (like button,label,image, couple of custom wigets etc) inside this page. A simple scenario though but our widgets are dynamic in the sense their content (for simplicity text in label) is updated at runtime. In other words certain properties are dynamic in the widgets. Hence we do have a controller which takes care of synching these properties. So far this approach is working well with QWidgets. Now that we are replacing QWidgets with QML, we have the following approach.

    Approach: We have put the controller as a QObject class and inject this controller as a context property into QML (via QDeclarativeContext) so that the controller is accessible in the respective qml item. Certain properties like text in label are bound using property bindings with controller. To make this simple for POC purpose, we are creating a QDeclarativeView and showing the QML. Since we want to move entirely on QML, we don't want to use QDeclarativeView for each widget anymore.

    Problem: As mentioned before, we want these dynamic widgets to be placed inside a page. We can very well generate the page's qml and load it. But these widgets don't have any meaning without the proper controller handling the dynamic properties. Hence I am thinking about making each widget (even a button is customized to some extent in our case, this customization is not the point of interest here) as a self contained QDeclarativeItem. Self contained in the sense that the required controller is also injected as a context property and the item is loaded and get going. I don't want to load these QDeclarativeItems into graphics scene as I don't want to tightly bind them to a particular QML backend. That being said, how can I do the following ...

    1. Can I load the widget as a QML Component using a QML Loader or something and inject the QObject controller into it via QML code itself?
    2. (or) If I create the self contained QDeclarativeItem, how can I place it in QML from C++.

    Is there any other better approach to this problem?

    Thanks for bearing with the long post, I just want to be more explicit.
    Srikanth Sombhatla

    1. You can. But as widget you mean QWidget type?
    2. With "qmlRegisterType":

  • Widget means a custom QML item. Like

    // ButtonController.h
    class ButtonController:public QObject {
    Q_PROPERTY(QString text READ text NOTIFY textChanged)

    Component {
    Text {
    text:{controller.text} // property binding with controller

    I want to use this CustomButton component in a another qml, where the controller for each CustomButton instance is different, like i may load the CustomButton Component via a QML Loader, but I want to inject a different controller for each CustomButton.

  • Yes, I have seen about qmlRegisterType, but how to inject a different QObject as a context property though via QML itself.

  • I found an approach to this problem, posting here so that someone with the same issue can get a clue of it.

    QML has "dynamic object creation ": which we can create a qml item providing the source. Once an object is created from a component, it can treated just like a qml item, accessing it properties.

    Rectangle {
    id: parentView
    function createQmlObject() {
    var component = Qt.createComponent("MyQml.qml");
    var qmlObject = component.createObject(parentView);
    // inject the controller
    qmlObject.controller = controllerForThisQmlWidget;

Log in to reply