Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. General talk
  3. Brainstorm
  4. JavaScript references in QML
Forum Update on Monday, May 27th 2025

JavaScript references in QML

Scheduled Pinned Locked Moved Solved Brainstorm
3 Posts 1 Posters 525 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.
  • M Offline
    M Offline
    mzimmers
    wrote on 4 Oct 2023, 15:30 last edited by
    #1

    Hi all -

    I have a QML object (defined in C++) with a large number of members, most of which are enums. The values are selected using a ListView with RadioDelegates, which appear in a Drawer.

    I'm trying to write a utility component to display the lists and return the selection. Where I'm stuck is how to return the selection. From the reading I've done, it appears that I need to use JavaScript references, but I can't make it work.

    I access the utility list via a Component:

    Component {
        id: actionComponent
        ScheduleList {
            onFinished: // signal within ScheduleList
                (ind, selection) => {
                            // need some kind of assignment HERE.
                            scheduleDetailsStackView.clear()
                            scheduleDetailsDrawer.close()
                        }
        }
    }
    

    And I invoke this in several places, like this:

    Button {
        onClicked: {
            scheduleDetailsStackView.clear()
            scheduleDetailsStackView.push(actionComponent, { "listModel": listPanel.actionModel })
            scheduleDetailsDrawer.open()
        }
    }
    

    So, how can I get my utility list to assign the selected value to a particular member of my object? I've implemented a callback that can assign the value to a hard-coded variable, but doing it this way would mean I'd need a separate callback for each member of the object.

    Is this the best I can do, or is there some JS magic that I can use?

    Thanks for any ideas...

    M 1 Reply Last reply 4 Oct 2023, 20:45
    0
    • M mzimmers
      4 Oct 2023, 20:45

      I've solved part of it, by adding a callback function to my ScheduleList component:

      // ScheduleList.qml
      ColumnLayout {
          required property var listModel
          required property var callback
      
          ButtonBar { // custom button bar
              onButtonClicked: (ind) => {
                                   callback(list.currentIndex)
                               }
              }
          }
          // ...
      }
      

      and invoking it with an arrow function, with different arguments for each button:

      Button {
          id: actionButton
          onClicked {
              scheduleDetailsStackView.push(
                          actionComponent,
                          {
                              "listModel": listPanel.actionModel,
                              "callback": ((i) => newSchedule.startAction = i )
                          }
      
      Button {
          id: whenButton
          onClicked {
              scheduleDetailsStackView.push(
                          actionComponent,
                          {
                              "listModel": listPanel.whenModel,
                              "callback": ((i) => newSchedule.startWhen = i )
                          }
                          )
      // and so on.
      

      I said "solved part of it" above, because I'm not yet finished -- these buttons that use the list component are themselves inside a Component that is re-used (for start and stop operations). Now I have to figure out how to tell this component which object members I want to use. I think I still need to use JS references, so anyone with some experience here, please feel free to advise.

      Thanks...

      M Offline
      M Offline
      mzimmers
      wrote on 16 Oct 2023, 21:08 last edited by
      #3

      Fixed it -- I added a bool to my parent property to tell me whether this button belongs to to the start or end panel, and I check that bool in my callback.

      Button {
          id: action
          buttonText: actionButtonLabel
          onClicked: {
              stackView.clear()
              stackView.push(
                          actionComponent,
                          {
                              "listModel": scheduleActionPanel.actionModel,
                              "listIndex": isStartPanel ? newSchedule.startAction : newSchedule.endAction,
                              "buttonGroup": startStopGroup,
                              "titleText": scheduleActionPanel.actionTitle,
                              "callback": ((i) => {
                                               if (isStartPanel) {
                                                   newSchedule.startAction = i
                                               } else {
                                                   newSchedule.endAction = i
                                               }
                                           }
                                           )
                          }
                          )
          }
      }
      

      If necessary, the bool could be replaced by an int, and the callback logic made more elaborate.

      1 Reply Last reply
      0
      • M mzimmers
        4 Oct 2023, 15:30

        Hi all -

        I have a QML object (defined in C++) with a large number of members, most of which are enums. The values are selected using a ListView with RadioDelegates, which appear in a Drawer.

        I'm trying to write a utility component to display the lists and return the selection. Where I'm stuck is how to return the selection. From the reading I've done, it appears that I need to use JavaScript references, but I can't make it work.

        I access the utility list via a Component:

        Component {
            id: actionComponent
            ScheduleList {
                onFinished: // signal within ScheduleList
                    (ind, selection) => {
                                // need some kind of assignment HERE.
                                scheduleDetailsStackView.clear()
                                scheduleDetailsDrawer.close()
                            }
            }
        }
        

        And I invoke this in several places, like this:

        Button {
            onClicked: {
                scheduleDetailsStackView.clear()
                scheduleDetailsStackView.push(actionComponent, { "listModel": listPanel.actionModel })
                scheduleDetailsDrawer.open()
            }
        }
        

        So, how can I get my utility list to assign the selected value to a particular member of my object? I've implemented a callback that can assign the value to a hard-coded variable, but doing it this way would mean I'd need a separate callback for each member of the object.

        Is this the best I can do, or is there some JS magic that I can use?

        Thanks for any ideas...

        M Offline
        M Offline
        mzimmers
        wrote on 4 Oct 2023, 20:45 last edited by
        #2

        I've solved part of it, by adding a callback function to my ScheduleList component:

        // ScheduleList.qml
        ColumnLayout {
            required property var listModel
            required property var callback
        
            ButtonBar { // custom button bar
                onButtonClicked: (ind) => {
                                     callback(list.currentIndex)
                                 }
                }
            }
            // ...
        }
        

        and invoking it with an arrow function, with different arguments for each button:

        Button {
            id: actionButton
            onClicked {
                scheduleDetailsStackView.push(
                            actionComponent,
                            {
                                "listModel": listPanel.actionModel,
                                "callback": ((i) => newSchedule.startAction = i )
                            }
        
        Button {
            id: whenButton
            onClicked {
                scheduleDetailsStackView.push(
                            actionComponent,
                            {
                                "listModel": listPanel.whenModel,
                                "callback": ((i) => newSchedule.startWhen = i )
                            }
                            )
        // and so on.
        

        I said "solved part of it" above, because I'm not yet finished -- these buttons that use the list component are themselves inside a Component that is re-used (for start and stop operations). Now I have to figure out how to tell this component which object members I want to use. I think I still need to use JS references, so anyone with some experience here, please feel free to advise.

        Thanks...

        M 1 Reply Last reply 16 Oct 2023, 21:08
        0
        • M mzimmers
          4 Oct 2023, 20:45

          I've solved part of it, by adding a callback function to my ScheduleList component:

          // ScheduleList.qml
          ColumnLayout {
              required property var listModel
              required property var callback
          
              ButtonBar { // custom button bar
                  onButtonClicked: (ind) => {
                                       callback(list.currentIndex)
                                   }
                  }
              }
              // ...
          }
          

          and invoking it with an arrow function, with different arguments for each button:

          Button {
              id: actionButton
              onClicked {
                  scheduleDetailsStackView.push(
                              actionComponent,
                              {
                                  "listModel": listPanel.actionModel,
                                  "callback": ((i) => newSchedule.startAction = i )
                              }
          
          Button {
              id: whenButton
              onClicked {
                  scheduleDetailsStackView.push(
                              actionComponent,
                              {
                                  "listModel": listPanel.whenModel,
                                  "callback": ((i) => newSchedule.startWhen = i )
                              }
                              )
          // and so on.
          

          I said "solved part of it" above, because I'm not yet finished -- these buttons that use the list component are themselves inside a Component that is re-used (for start and stop operations). Now I have to figure out how to tell this component which object members I want to use. I think I still need to use JS references, so anyone with some experience here, please feel free to advise.

          Thanks...

          M Offline
          M Offline
          mzimmers
          wrote on 16 Oct 2023, 21:08 last edited by
          #3

          Fixed it -- I added a bool to my parent property to tell me whether this button belongs to to the start or end panel, and I check that bool in my callback.

          Button {
              id: action
              buttonText: actionButtonLabel
              onClicked: {
                  stackView.clear()
                  stackView.push(
                              actionComponent,
                              {
                                  "listModel": scheduleActionPanel.actionModel,
                                  "listIndex": isStartPanel ? newSchedule.startAction : newSchedule.endAction,
                                  "buttonGroup": startStopGroup,
                                  "titleText": scheduleActionPanel.actionTitle,
                                  "callback": ((i) => {
                                                   if (isStartPanel) {
                                                       newSchedule.startAction = i
                                                   } else {
                                                       newSchedule.endAction = i
                                                   }
                                               }
                                               )
                              }
                              )
              }
          }
          

          If necessary, the bool could be replaced by an int, and the callback logic made more elaborate.

          1 Reply Last reply
          0
          • M mzimmers has marked this topic as solved on 16 Oct 2023, 21:08

          • Login

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