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. Design Patterns QML & C++
Forum Updated to NodeBB v4.3 + New Features

Design Patterns QML & C++

Scheduled Pinned Locked Moved QML and Qt Quick
9 Posts 8 Posters 10.6k Views 4 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.
  • L Offline
    L Offline
    lunatic
    wrote on last edited by
    #1

    Are there any good Design Patterns for QML & C++ ?

    I mean, I understood the sense of QML. It's there to separate UI from Logic.
    But I have some problems...
    ...Example given:

    • Problem: I have a QML-ListView which should be filled from the C++-Code, by loading the data from a SQL database.
      Question: What's the solution? How can I fill the QML-ListView with the given data from the C++-Code?

    • Problem: The user clicks on one of the items in the ListView. The C++-Code must know which item the user clicked.
      Question: How does the C++-Code know which item was clicked by the user?

    • Problem: The e.g.: MyMainMenu.qml has lots of nested elements. Some elements have signals, which will be raised if the user clicks on it.
      Question: How does the C++-Code connects to these signals?

    • Problem: The UI has a main menu. If the user clicks on e.g.: News, the C++-Code receives the Click-Signal and shows the News.qml file.
      Question: How should I implement such a concept? I mean: How could I switch from one .qml file to the other? (With a nice effect).

    It would be awesome if you could provide examples to these questions.

    Thanks,
    lunatic

    1 Reply Last reply
    0
    • R Offline
      R Offline
      Ramblurr
      wrote on last edited by
      #2

      This is quite a question. Pretty much each of those problems deserves its own thread, or better yet a wiki page.

      Regarding:

      bq. Some elements have signals, which will be raised if the user clicks on it.
      Question: How does the C++-Code connects to these signals?

      C++ can't directly connect to QML signals, so I suggest handling the signals in QML and calling the slot/method on the C++ object.

      Example:
      @onClicked: { _someCPPObject.somethingClicked() }@

      (it is a good convention to prefix your C++ objects in QML with an underscore)

      bq. Problem: The UI has a main menu. If the user clicks on e.g.: News, the C++-Code receives the Click-Signal and shows the News.qml file.
      Question: How should I implement such a concept? I mean: How could I switch from one .qml file to the
      As for switching between QML files. This is a complex topic. other? (With a nice effect).

      As for switching between QML files. This is a complex topic. First, don't think of it as "switching" QML files.

      Instead, your News.qml file should declare a single QML Element (probably an Item element), and some other QML file (like your mainwindow.qml) will include it with:

      @ News {
      // news properties and anchors, etc
      }@

      You should think of your QML UI as a tree of QML elements that is loaded all at once by loading your main QML source. You accomplish switching between screens (not files) by effectively changing which node in the tree is currently displayed. Do this by setting the 'visibility' property on your QML elements.

      Personally, I like to have a global C++ object (where global means accessible in QML) with an enum for each screen. Then I have a currentScreen Q_PROPERTY and set my QML elements like so:

      @
      SomeElement {
      visible: _screenInfo.currentScreen == ScreenInfo.SomeEnum
      // ...
      }
      @

      Note that I am using the declarative model here. No where do I need an if statement like:

      @if (currentScreen() != ScreenInfo.SomeEnum ) {
      SomeElement.visible = false
      };@

      That kind of code gets messy fast, and is unnecessary in QML.

      The screens themselves can be a composition of many sub-elements. Thinking in terms of a tree is important.

      Handling the flow between screens can be a daunting task. Using a QStateMachine makes it much easier and maintainable. Unfortunately I don't know of any wiki articles or guides explaining how to do this, but I did find "this mailing list post":http://www.mail-archive.com/qt-qml@trolltech.com/msg01739.html that is a good primer.

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

        All problems can be solved if you go with UI-Controller approach. Here QML is your UI, keep it as dump as possible. Controller is a QObject based class exposing required methods as slots, signals, Q_INVOKABLE and Q_PROPERTY.

        Now inject each controller into the qml as a QtObject property and handle the logic accordingly.

        For ListView ( I would say models in QML ), derive your class from QAbstractListModel and handle it accordingly. You can also create a simple count based model also. See "here":http://developer.qt.nokia.com/forums/viewthread/8929/#53644.

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

          All of your questions are answered in a common topic "Extending QML using C++"

          http://doc.qt.nokia.com/4.7-snapshot/qml-extending.html
          http://doc.qt.nokia.com/4.7-snapshot/qdeclarativemodels.html#c-data-models

          And "Using QML in C++"
          http://doc.qt.nokia.com/latest/qtbinding.html

          The pages have examples as well.

          1 Reply Last reply
          0
          • R Offline
            R Offline
            raja26
            wrote on last edited by
            #5

            If you are just going to load the Listview from DB, you can simply use the SQL support in QML itself. But, if there are going to be any manipulations, you gotta go for C++, personally I feel, the ObjectListModel and QStringList model are much easier to use and write code.

            If the user clicks on the ListView item: you should have defined a delegate for that ListView with a MouseArea, that will send the "text" or whatever the delegate has, to the CPP method. TO implement this, you should follow Casey's rule.

            Follow Kypeli's "Using QML..." link for achieving your third use case.

            For the switching QML (like, page transition effect), it is always better to go for Dynamically loaded QML components, because I have used a dirty way to achieve this and the application consumes 20 MB of RAM for it. I would suggest you to go for Opacity based transition, i.e. decrease the opacity of the first page and then increase the Opacity of the second page. If the switching is too infrequent to maintain the Pages in the memory, you can load all the pages dynamically and destroy them as desired.

            If you search around the documentation, you can find examples for all your use cases with fine examples.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              minimoog77
              wrote on last edited by
              #6

              [quote author="raja26" date="1315331802"]If you are just going to load the Listview from DB, you can simply use the SQL support in QML itself. But, if there are going to be any manipulations, you gotta go for C++, personally I feel, the ObjectListModel and QStringList model are much easier to use and write code.[/quote]

              There is only SQLite support in QML. In the future I don't know. I would go with "QAbstractListModel":http://doc.qt.nokia.com/latest/qabstractlistmodel.html .

              1 Reply Last reply
              0
              • R Offline
                R Offline
                raja26
                wrote on last edited by
                #7

                [quote author="minimoog77" date="1315395490"]
                There is only SQLite support in QML. In the future I don't know. I would go with "QAbstractListModel":http://doc.qt.nokia.com/latest/qabstractlistmodel.html . [/quote]
                Yes, indeed there is SQLite support alone. I though you were developing for mobile.

                All the best.

                1 Reply Last reply
                0
                • benlauB Offline
                  benlauB Offline
                  benlau
                  Qt Champions 2016
                  wrote on last edited by
                  #8

                  Action-Dispatcher Design Pattern for QML — Medium

                  This article is my answer to problem 2 & 3.

                  1 Reply Last reply
                  0
                  • GTDevG Offline
                    GTDevG Offline
                    GTDev
                    wrote on last edited by
                    #9

                    While the Qt framework is C++ based, you can also code with QML and JavaScript. In fact, you can create full apps without even touching C++.

                    We've prepared a comprehensive guide how to structure QML-driven apps, along with many available demos and examples that follow this approach!

                    Check out the full developer guide here: https://v-play.net/apps/avoid-cpp-models-qt

                    Senior Developer at Felgo - https://felgo.com/qt

                    Develop mobile Apps for iOS & Android with Qt
                    Felgo is an official Qt Technology Partner

                    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