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. Access C++ factory-created objects from QML
QtWS25 Last Chance

Access C++ factory-created objects from QML

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
factorydynamic
4 Posts 3 Posters 846 Views
  • 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
    LordKalma
    wrote on 13 Mar 2021, 16:29 last edited by
    #1

    Hey there.

    I'm developing an application with a C++ backend and a QML frontend and I'm having troubles.

    So, what I want to do is the following:

    • A factory class of some sort is exposed to QML using setContextProperty.
    • The objects the factory outputs controller classes for different hardware devices.
    • Each device has a different set of controls, that I want to write as independent QML files.
    • Then, I need to get this newly created controller, access some function of it to return the QML resource, and display it. I guess a Loader would work.

    The question then is about how to make the QML file for a specific controller know about the controller object? In the QWidgets world what I do is just make a custom QWidget that has a pointer to the controller (and vice-versa, actually). But now I don't know how to do this in QML.

    In fact, I'm not even sure this is the right architecture.

    I'll leave here an image explaining what I want to do:
    diagram

    Thanks!

    1 Reply Last reply
    1
    • V Offline
      V Offline
      VStevenP
      wrote on 22 Mar 2021, 15:12 last edited by VStevenP
      #2

      Maybe this is what you're looking for: https://doc.qt.io/qt-5/qtqml-javascript-dynamicobjectcreation.html

      1 Reply Last reply
      0
      • V Offline
        V Offline
        VStevenP
        wrote on 22 Mar 2021, 15:33 last edited by VStevenP
        #3

        That should solve the question of "How can this QML be displayed?"

        Other question: "How can QML call this object method?".
        Answer: The QML code inside some_file.qml must refer to the object you exposed via setContextProperty for the specific radio. So, if you called setContextProperty() with an object name of "specificRadio", then in some_file.qml, you could have the following somewhere in a code block, assuming volume member has been exposed to QML via a setVolume() setter:

        specificRadio.setVolume(100)

        You could also use models to bind to data of your radio class.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          jeremy_k
          wrote on 23 Mar 2021, 01:11 last edited by
          #4

          Do these objects output by the factory have a lifetime that needs to exceed the QML component used for the object's controls? If not, I would make the object a QML (not Quick) type, and have the component that displays the controls also instantiate the object.

          Even if they do have lifetimes that don't match the UI portion, the controls can be thin wrappers around the objects that really implement the backend. In the example below RadioBackend and TapeBackend are QObject derived classes that export Q_INVOKABLE functions and properties for communication with the UI. Register them with one of the qmlRegister* functions, depending on the desired interface.

          For example:

          Radio.qml:

          Rectangle {
              color: control.colorTheme
              RadioBackend { id: control }
              Row {
                  Button {
                      onClicked: control.doAction()
                  }
                  Button {
                      onClicked: control.doOtherAction()
                  }
              }
          }
          

          TapeDeck.qml:

          Rectangle {
              color: control.colorTheme
              TapeBackend { id: control }
              Button {
                  onClicked: control.doTapeAction()
              }
          }
          

          main.qml:

          Loader {
              property MediaType mediaType
              source: mediaType === MediaType.Radio ? "file://Radio.qml"
                                                    : "file://TapeDeck.qml"
          }    
          

          Asking a question about code? http://eel.is/iso-c++/testcase/

          1 Reply Last reply
          1

          • Login

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