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. Passing array of QML elements to Javascript function

Passing array of QML elements to Javascript function

Scheduled Pinned Locked Moved Solved QML and Qt Quick
5 Posts 2 Posters 1.7k 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.
  • G Offline
    G Offline
    Gizmo
    wrote on 3 Sept 2018, 05:40 last edited by
    #1

    This is my first time using a declarative language and I have run into a few issues.

    This application is meant to help count currency by number of units input by the user and displays the total face value to the user.

    0_1535952294851_Untitled.png

    My first problem is I'm sending 9 elements to my FormCalculations.tillBalanceHandler individually

    Is there a way to send something like... parent.children? and if so how do I reference them individually inside the javascript function?

    //this is my main qml file
    Page1Form 
    {
    //Handle calculations of tillBalanceNum
    tillBalanceNum.text: FormCalculations.tillBalanceHandler(quarterRollCalc, dimeRollCalc, nickelRollCalc, pennyRollCalc, tillQuarterCalc, tillNickelsCalc, tillDimesCalc, tillPennyCalc, extraChangeCalc)
    }
    //this is a small clip of how my elements in ui.qml look
    Column {
            id: column
            x: 5
            width: 80
            height: 316
            spacing: 13
    
            Text {
                id: quarterRolls
                width: 80
                height: 20
                text: qsTr("quarter rolls")
                font.family: "Verdana"
                font.pixelSize: 12
    
            }
    
            Text {
                id: dimeRolls
                width: 80
                height: 20
                text: qsTr("dime rolls")
                font.family: "Verdana"
                font.pixelSize: 12
            }
    Column {
            id: column1
            x: 129
            y: 0
            width: 42
            height: 316
            spacing: 13
    
            TextInput {
                id: quarterRollCount
                width: 30
                height: 20
                text: qsTr("#")
                validator: IntValidator{bottom:1; top:1000}
                font.pixelSize: 12
                property double value: 10.00
    
    
            }
    
            TextInput {
                id: dimeRollCount
                width: 30
                height: 20
                text: qsTr("#")
                validator: IntValidator{bottom:1; top:1000}
                font.pixelSize: 12
                property double value: 5.00
    
            }
    Column {
            id: column2
            x: 217
            y: 0
            width: 42
            height: 316
            spacing: 13
    
            Text {
                id: quarterRollCalc
                width: 80
                height: 20
                font.pixelSize: 12
            }
    
            Text {
                id: dimeRollCalc
                width: 80
                height: 20
                font.pixelSize: 12
            }
    
    //this is my javascript file
    function tillBalanceHandler(QRC, DRC, NRC, PRC, TQC, TDC, TNC, TPC, ECC)
        {
        var calcArray = [QRC.text, DRC.text, NRC.text, PRC.text, TQC.text, TDC.text, TNC.text, TPC.text, ECC.text]
        var iterator
        var totalToSubtract = 225
            for (iterator in calcArray)
            {
            totalToSubtract = totalToSubtract - calcArray[iterator]
            }
    
        //result needs 2 digits after decimal
        var result = totalToSubtract.toFixed(2)
    
        return result
        }
    
    

    my 2nd problem if possible is if someone could tell me if it's possible to batch together SignalHandlers?

    //main.qml again
    Page1Form {
                //Handle Edits to Counts to Display Totals
                quarterRollCount.onEditingFinished: {quarterRollCalc.text = FormCalculations.countHandler(quarterRollCount)}
                dimeRollCount.onEditingFinished: {dimeRollCalc.text = FormCalculations.countHandler(dimeRollCount)}
                nickelRollCount.onEditingFinished: {nickelRollCalc.text = FormCalculations.countHandler(nickelRollCount)}
                pennyRollCount.onEditingFinished: {pennyRollCalc.text = FormCalculations.countHandler(pennyRollCount)}
                tillQuarterCount.onEditingFinished: {tillQuarterCalc.text = FormCalculations.countHandler(tillQuarterCount)}
                tillNickelCount.onEditingFinished: {tillNickelsCalc.text = FormCalculations.countHandler(tillNickelCount)}
                tillDimeCount.onEditingFinished: {tillDimesCalc.text = FormCalculations.countHandler(tillDimeCount)}
                tillPenniesCount.onEditingFinished: {tillPennyCalc.text = FormCalculations.countHandler(tillPenniesCount)}
                extraChangeCount.onEditingFinished: {extraChangeCalc.text = FormCalculations.countHandler(extraChangeCount)}
    }
    //javascript file
    function countHandler(countElement)
        {
        var countInt = parseInt(countElement.text)
        var value = countElement.value
    
        var total = (countInt * value).toFixed(2)
    
        return total
        }
    

    If anyone has suggestions for how to approach QML/Javascript in this context, please do so I can make my life easier
    thanks!

    D 1 Reply Last reply 3 Sept 2018, 14:57
    0
    • G Gizmo
      3 Sept 2018, 05:40

      This is my first time using a declarative language and I have run into a few issues.

      This application is meant to help count currency by number of units input by the user and displays the total face value to the user.

      0_1535952294851_Untitled.png

      My first problem is I'm sending 9 elements to my FormCalculations.tillBalanceHandler individually

      Is there a way to send something like... parent.children? and if so how do I reference them individually inside the javascript function?

      //this is my main qml file
      Page1Form 
      {
      //Handle calculations of tillBalanceNum
      tillBalanceNum.text: FormCalculations.tillBalanceHandler(quarterRollCalc, dimeRollCalc, nickelRollCalc, pennyRollCalc, tillQuarterCalc, tillNickelsCalc, tillDimesCalc, tillPennyCalc, extraChangeCalc)
      }
      //this is a small clip of how my elements in ui.qml look
      Column {
              id: column
              x: 5
              width: 80
              height: 316
              spacing: 13
      
              Text {
                  id: quarterRolls
                  width: 80
                  height: 20
                  text: qsTr("quarter rolls")
                  font.family: "Verdana"
                  font.pixelSize: 12
      
              }
      
              Text {
                  id: dimeRolls
                  width: 80
                  height: 20
                  text: qsTr("dime rolls")
                  font.family: "Verdana"
                  font.pixelSize: 12
              }
      Column {
              id: column1
              x: 129
              y: 0
              width: 42
              height: 316
              spacing: 13
      
              TextInput {
                  id: quarterRollCount
                  width: 30
                  height: 20
                  text: qsTr("#")
                  validator: IntValidator{bottom:1; top:1000}
                  font.pixelSize: 12
                  property double value: 10.00
      
      
              }
      
              TextInput {
                  id: dimeRollCount
                  width: 30
                  height: 20
                  text: qsTr("#")
                  validator: IntValidator{bottom:1; top:1000}
                  font.pixelSize: 12
                  property double value: 5.00
      
              }
      Column {
              id: column2
              x: 217
              y: 0
              width: 42
              height: 316
              spacing: 13
      
              Text {
                  id: quarterRollCalc
                  width: 80
                  height: 20
                  font.pixelSize: 12
              }
      
              Text {
                  id: dimeRollCalc
                  width: 80
                  height: 20
                  font.pixelSize: 12
              }
      
      //this is my javascript file
      function tillBalanceHandler(QRC, DRC, NRC, PRC, TQC, TDC, TNC, TPC, ECC)
          {
          var calcArray = [QRC.text, DRC.text, NRC.text, PRC.text, TQC.text, TDC.text, TNC.text, TPC.text, ECC.text]
          var iterator
          var totalToSubtract = 225
              for (iterator in calcArray)
              {
              totalToSubtract = totalToSubtract - calcArray[iterator]
              }
      
          //result needs 2 digits after decimal
          var result = totalToSubtract.toFixed(2)
      
          return result
          }
      
      

      my 2nd problem if possible is if someone could tell me if it's possible to batch together SignalHandlers?

      //main.qml again
      Page1Form {
                  //Handle Edits to Counts to Display Totals
                  quarterRollCount.onEditingFinished: {quarterRollCalc.text = FormCalculations.countHandler(quarterRollCount)}
                  dimeRollCount.onEditingFinished: {dimeRollCalc.text = FormCalculations.countHandler(dimeRollCount)}
                  nickelRollCount.onEditingFinished: {nickelRollCalc.text = FormCalculations.countHandler(nickelRollCount)}
                  pennyRollCount.onEditingFinished: {pennyRollCalc.text = FormCalculations.countHandler(pennyRollCount)}
                  tillQuarterCount.onEditingFinished: {tillQuarterCalc.text = FormCalculations.countHandler(tillQuarterCount)}
                  tillNickelCount.onEditingFinished: {tillNickelsCalc.text = FormCalculations.countHandler(tillNickelCount)}
                  tillDimeCount.onEditingFinished: {tillDimesCalc.text = FormCalculations.countHandler(tillDimeCount)}
                  tillPenniesCount.onEditingFinished: {tillPennyCalc.text = FormCalculations.countHandler(tillPenniesCount)}
                  extraChangeCount.onEditingFinished: {extraChangeCalc.text = FormCalculations.countHandler(extraChangeCount)}
      }
      //javascript file
      function countHandler(countElement)
          {
          var countInt = parseInt(countElement.text)
          var value = countElement.value
      
          var total = (countInt * value).toFixed(2)
      
          return total
          }
      

      If anyone has suggestions for how to approach QML/Javascript in this context, please do so I can make my life easier
      thanks!

      D Offline
      D Offline
      Diracsbracket
      wrote on 3 Sept 2018, 14:57 last edited by Diracsbracket 9 Mar 2018, 15:46
      #2

      @Gizmo
      You should really have a look at:
      http://doc-snapshots.qt.io/qt5-5.11/qtquick-modelviewsdata-modelview.html
      It will solve both your problems...

      To get you going, try the following:

          ListModel {
              id: myModel
              ListElement {denomination: "quarter rolls"; unitValue: 10.0}
              ListElement {denomination: "dime rolls"; unitValue: 5.0}
              ListElement {denomination: "nickel rolls"; unitValue: 2.0}
              ListElement {denomination: "penny rolls"; unitValue: 0.50}
              ListElement {denomination: "till quarters"; unitValue: 0.25}
              ListElement {denomination: "till dimes"; unitValue: 0.10}
              ListElement {denomination: "till nickels"; unitValue: 0.05}
              ListElement {denomination: "till pennies"; unitValue: 0.01}
          }
      
          Column {
              height: 20*myModel.count
              width: 80
              padding: 10
      
              Repeater {
                  id: test
                  model: myModel
      
                  delegate: Row {
                      height: 30
                      width: 100
                      Text {
                          id: denomLabel
                          width: 100
                          height: 30
                          font.pixelSize: 12
                          text: denomination
                      }
      
                      TextInput {
                         id: countVal
                          width: 100
                          height: 30
                          text: "1"
                          validator: IntValidator{bottom:1; top:1000}
                          font.pixelSize: 12
                          onAccepted: {
                              totVal.text = (unitValue * parseInt(countVal.text)).toFixed(2)
                          }
                      }
      
                      Text {
                          id: totVal
                          width: 80
                          height: 30
                          font.pixelSize: 12
                          text: unitValue.toFixed(2) //(unitValue * parseInt(countVal.text)).toFixed(2)
                      }
                  }
              }
          }
      

      You can access model items via the get(index) method and items from the Repeater via the itemAt(index) method to access the values in the delegate that are not part of the model.

      Good luck!

      1 Reply Last reply
      1
      • G Offline
        G Offline
        Gizmo
        wrote on 5 Sept 2018, 09:55 last edited by
        #3

        I'm currently working with "totVal" and I need to access it within your solution.
        How do I access the index of TotVal with itemAt()?
        At this point I'm curious to reassign the index each time totVal is created within the repeater.

        I had totVal tell me the index of itself, but it seems the row is creating a problem?
        I tried to assume perhaps it could be an array, (RowNum, ElementNum) but that didn't work either.
        I tried test.itemAt(0).totVal and that didn't work either.
        I'm able to see that test.itemAt(up to myModel.count).width only gives me the width of what the row is.

        D 1 Reply Last reply 5 Sept 2018, 17:37
        0
        • G Gizmo
          5 Sept 2018, 09:55

          I'm currently working with "totVal" and I need to access it within your solution.
          How do I access the index of TotVal with itemAt()?
          At this point I'm curious to reassign the index each time totVal is created within the repeater.

          I had totVal tell me the index of itself, but it seems the row is creating a problem?
          I tried to assume perhaps it could be an array, (RowNum, ElementNum) but that didn't work either.
          I tried test.itemAt(0).totVal and that didn't work either.
          I'm able to see that test.itemAt(up to myModel.count).width only gives me the width of what the row is.

          D Offline
          D Offline
          Diracsbracket
          wrote on 5 Sept 2018, 17:37 last edited by Diracsbracket 9 May 2018, 19:45
          #4

          @Gizmo
          You are right in that it has to do with the Row. You cannot directly access totVal since it is not the root of the delegate. In your case the root is the Row indeed. To access children of the delegate's root object, or their properties, you have to use an alias, for example like this:

                  Repeater {
                      id: test
                       ...
          
                      delegate: Row {
                            ...
                           property alias sumVal: totVal.text
                            ...
                           Text {
                                 id: totVal
                                 text: ...
                           }
                       }
                  } 
          

          Now, you can access sumVal as:

          test.itemAt(index).sumVal
          

          Note that aliases can also be to the object itself, so you could instead have done:

              property alias totVal: totVal
          

          and then use:

          test.itemAt(index).totVal.text
          

          to get the text value.

          1 Reply Last reply
          1
          • G Offline
            G Offline
            Gizmo
            wrote on 6 Sept 2018, 01:50 last edited by Gizmo 9 Jun 2018, 01:56
            #5

            Hahaha that's fantastic, I tried the property alias within the totVal {block} and it didn't work with all of this code inside my ui.qml. I finally realized that placing all of this in my main qml file makes life much easier and I have more freedom. Thanks again Diracsbracket.

            0_1536199001859_Untitled.png

            1 Reply Last reply
            0

            5/5

            6 Sept 2018, 01:50

            • Login

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