Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. C++ class updating properties for QML elements
Forum Updated to NodeBB v4.3 + New Features

C++ class updating properties for QML elements

Scheduled Pinned Locked Moved QML and Qt Quick
6 Posts 4 Posters 3.7k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • AlicemirrorA Offline
    AlicemirrorA Offline
    Alicemirror
    wrote on last edited by
    #1

    Hi to all,

    I have a problem and two solutions. I will know what is the best. The scenario is the following:

    In some cases I have a set of properties e.g. width and height of a object from which other properties depends on (bound to it) e.g. button_size and button_spacing. The relation is based on some algoritm e.g. button_size = getButtonSize(width) and button_spacing = getButtonSpacing(width, height)

    The possible solutions are the following:

    I create a Qt/C++ class ButtonsProperties that exposes only properties to the QML document. This means that in the C++ class I expose the following QOBJECT components:

    • btnSpacing
    • btnSize
    • width
    • height

    Then in Qml I create the following:

    @
    ButtonProperties {
    id: myButtonClass

    width: parent.width
    height: parent.height
    

    }
    @
    Then when the element is set in the QML document I can use the other property for which the class has calculated the value as in the following example:
    @
    Recatngle {
    id: myButton
    width: myButtonClass.btnSize
    height: myButtonClass.btnSize
    }
    @

    and so on.

    The alternative is to explicitly declare the calculation functions as INVOKABLE in the C++ class so I can use the method itself when I set the property in the QML document as in the following example.

    @
    Rectangle {
    id: myButton
    width: myButtonClass.getBtnSize(parent.widht)
    height: myButtonClass.getBtnSize(parent.width)
    }
    @

    And so on. In both cases the binding is respected and there are no binding loops. What is the most correct usage ?

    Many thanks to all the suggestions.

    Enrico Miglino (aka Alicemirror)
    Balearic Dynamics
    Islas Baleares, Ibiza (Spain)
    www.balearicdynamics.com

    1 Reply Last reply
    0
    • K Offline
      K Offline
      Kypeli
      wrote on last edited by
      #2

      I would keep all UI related properties and especially calculations very far away from any C++ code. QML is there to create the UI for you so you are better off having everything there and keep application logic and processing in C++. This is what I suggest, although you can do all kinds of things in both QML and C++... I would just not advice for it :)

      So to your question; I would say definitely use the first approach.

      What comes to size calculation for UI based on some other properties; have you considered using states? In my own code I prefer to keep the logic in QML very light, as usually you don't need to write a lot of code to achieve the UI state changes. QML States is a perfect tool for this. You can put all the "logic" (states, connections...) of a component into a separate file and hook the component to some signals for example to do the state changes where you change the properties.

      1 Reply Last reply
      0
      • AlicemirrorA Offline
        AlicemirrorA Offline
        Alicemirror
        wrote on last edited by
        #3

        Hello Kipeli, every idea or advice is always welcome keeping my mind open :)

        I agree with your point of view; my question was also to investigate if a method was more complex and/or resource consuming respect the other. Working in QML keeping in mind only the properties and state changes seems best to me. I have tested the second method exposed above and when it worked I thought that the second was probably a more elegant and well structured way.

        Using a function in the C++ code based on properties assignement from QML that creates automatically the new properties as all the needed data (properties) are done solve the problem at all.

        In some cases there are methods that should be called as methods. When possible I keep these separated from the QML code using js components. When operation is simple to manage in C++ or it is necessary to manage parameters depending by the plaform I should use C++ classes where different behaviors are addressed with #ifdef preprocessor instructions.
        @
        #ifdef Q_OS_SYMBIAN
        #include "symbian_constants.h"
        #else
        #include "desktop_constants.h"
        #endif
        @
        So the same application remain full compatible with different platforms deciding what code should be used / included at compile time.

        Last, for methods that should remain methods I have found a way to register the class in QML without creating the corresponding object. I have not investigated in-depth in this direction and I am not sure if this is a good way to be adopted for direct function calls from QML. I try to simplify with an example:

        In C++ I create the class MyMethods and in main.cpp I register it.
        @
        QmlApplicationViewer viewer;
        // Construct FileHelper instance and expose it to QML.
        MyMethods myMethods;

        viewer.engine()->rootContext()->setContextProperty("myMethods", &myMethods);
        

        @
        so in QML I can use property assignements or events managing directly the method calls without defining any property:
        @
        Item {
        id: myItem
        width: myMethods.setWidth()
        ...
        @
        This last way don't require importing the class in the QML documents but it seems to me difficult to port and reuse it in more than one application.

        What do you thing about this?

        Many thanks.

        Enrico Miglino (aka Alicemirror)
        Balearic Dynamics
        Islas Baleares, Ibiza (Spain)
        www.balearicdynamics.com

        1 Reply Last reply
        0
        • K Offline
          K Offline
          Kypeli
          wrote on last edited by
          #4

          It sounds like you are creating one app for multiple platforms and every platform has its own UI - and you use the C++ code to remain portable between UIs?

          Well. If I were you I would simply create multiple QML UIs for each platforms (since it's so easy and fast), set the different UIs in their own folders, and then in C++ just load the appropriate "root UI" from the correct folder.

          I know this sounds like a lot of work and copy-pasting, but IMHO it's still more elegant and not really that much of work since it's mostly copying the UI files as they are into correct folders. This way you have the UI still separate from C++ and it's easier for you to make platform specific changes in the UI while keeping the logic the same.

          1 Reply Last reply
          0
          • D Offline
            D Offline
            dmcr
            wrote on last edited by
            #5

            Hi,

            A approch could be, i guess, to use a QDeclarativePropertyValueSource.
            Depending on circumstances, if you had to pass by the C++ and if the speed is important for the property you bind.

            dmcr

            1 Reply Last reply
            0
            • S Offline
              S Offline
              srikanth_trulyit
              wrote on last edited by
              #6

              Keep QML as dumb as possible: just layout your UI. Prefer to inject the properties as context property. If application logic is supplied by a well structured QObject, you can use it to any view possible like QWidget, QML, WebView, so one logic serves many views. When writing these engines (app logic) think view agnostic.

              1 Reply Last reply
              0

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved