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. Calculate TableView height according to Image in delegate
QtWS25 Last Chance

Calculate TableView height according to Image in delegate

Scheduled Pinned Locked Moved Solved QML and Qt Quick
9 Posts 3 Posters 863 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.
  • S Offline
    S Offline
    sandro4912
    wrote on last edited by sandro4912
    #1

    I have a TableView with the following output:

    f2cc7453-140d-42b6-9009-bfe6f00e4b4c-image.png

    Item {
        property string picture
        
        //...
    
        id: root
        Rectangle {
            id: rect
            anchors.fill: parent
            border.width: 1
            border.color: "black"
        }
    
        Image {
            id: image
            anchors.centerIn: parent
            source: root.picture.length > 0 ? "data:image/png;base64," + root.picture : ""
            fillMode: Image.PreserveAspectFit
            sourceSize.width: rect.width - rect.border.width * 2
            sourceSize.height: rect.height - rect.border.height * 2
        }
    
        //...
    }
    

    So I would have expected the Image fits in the rectangle but it does not.

    The TableView looks like this:

    Item {
        id: root
        
        //...
        
        HorizontalHeaderView {
            id: horizontalHeaderView
            syncView: tableView
            anchors.left: tableView.left
            model: [qsTr("Id"), qsTr("Question"), qsTr("Answer 1"), qsTr(
                    "Answer 2"), qsTr("Answer 3"), qsTr("Answer 4"), qsTr(
                    "Correct Answer"), qsTr("Picture")]
        }
        TableView {
            id: tableView
            width: parent.width
            height: parent.height - horizontalHeaderView.height
            anchors.top: horizontalHeaderView.bottom
            boundsBehavior: Flickable.StopAtBounds
    
            reuseItems: true
            clip: true
            property var columnWidths: [60, 220, 220, 220, 220, 220, 100, 140]
            columnWidthProvider: function (column) {
                return columnWidths[column]
            }
    
            model: questionsProxyModel
    
            delegate: DelegateChooser {
                id: chooser
    
                //... More DelegateChoices here for the other columns but not 
                //.. interesting for the issue here
                DelegateChoice {
                    column: 7
                    delegate: PictureDelegate {
                        id: pictureDelegate
                        width: tableView.columnWidthProvider(column)
                        picture: model.picture
                    }
                }
            }
            ScrollBar.vertical: ScrollBar {}
        }
    }
    
    

    So in the TableView I provide the width to each delegate via columnWidthProvider which works fine.

    The height is calculated automatically according to the content of the childs. This for example makes sure all the text always fits:

    a167dac0-0785-4e24-a37c-499b216aff5f-image.png

    Now how can I take the heigth the Image in the delegate needs to proper scale into account?

    ODБOïO 1 Reply Last reply
    0
    • S sandro4912

      I have a TableView with the following output:

      f2cc7453-140d-42b6-9009-bfe6f00e4b4c-image.png

      Item {
          property string picture
          
          //...
      
          id: root
          Rectangle {
              id: rect
              anchors.fill: parent
              border.width: 1
              border.color: "black"
          }
      
          Image {
              id: image
              anchors.centerIn: parent
              source: root.picture.length > 0 ? "data:image/png;base64," + root.picture : ""
              fillMode: Image.PreserveAspectFit
              sourceSize.width: rect.width - rect.border.width * 2
              sourceSize.height: rect.height - rect.border.height * 2
          }
      
          //...
      }
      

      So I would have expected the Image fits in the rectangle but it does not.

      The TableView looks like this:

      Item {
          id: root
          
          //...
          
          HorizontalHeaderView {
              id: horizontalHeaderView
              syncView: tableView
              anchors.left: tableView.left
              model: [qsTr("Id"), qsTr("Question"), qsTr("Answer 1"), qsTr(
                      "Answer 2"), qsTr("Answer 3"), qsTr("Answer 4"), qsTr(
                      "Correct Answer"), qsTr("Picture")]
          }
          TableView {
              id: tableView
              width: parent.width
              height: parent.height - horizontalHeaderView.height
              anchors.top: horizontalHeaderView.bottom
              boundsBehavior: Flickable.StopAtBounds
      
              reuseItems: true
              clip: true
              property var columnWidths: [60, 220, 220, 220, 220, 220, 100, 140]
              columnWidthProvider: function (column) {
                  return columnWidths[column]
              }
      
              model: questionsProxyModel
      
              delegate: DelegateChooser {
                  id: chooser
      
                  //... More DelegateChoices here for the other columns but not 
                  //.. interesting for the issue here
                  DelegateChoice {
                      column: 7
                      delegate: PictureDelegate {
                          id: pictureDelegate
                          width: tableView.columnWidthProvider(column)
                          picture: model.picture
                      }
                  }
              }
              ScrollBar.vertical: ScrollBar {}
          }
      }
      
      

      So in the TableView I provide the width to each delegate via columnWidthProvider which works fine.

      The height is calculated automatically according to the content of the childs. This for example makes sure all the text always fits:

      a167dac0-0785-4e24-a37c-499b216aff5f-image.png

      Now how can I take the heigth the Image in the delegate needs to proper scale into account?

      ODБOïO Offline
      ODБOïO Offline
      ODБOï
      wrote on last edited by
      #2

      hi
      @sandro4912 said in Calculate TableView height according to Image in delegate:

      fillMode: Image.PreserveAspectCrop

      did you try PreserveAspectFit ?
      https://doc.qt.io/qt-5/qml-qtquick-image.html#fillMode-prop

      S 1 Reply Last reply
      1
      • ODБOïO ODБOï

        hi
        @sandro4912 said in Calculate TableView height according to Image in delegate:

        fillMode: Image.PreserveAspectCrop

        did you try PreserveAspectFit ?
        https://doc.qt.io/qt-5/qml-qtquick-image.html#fillMode-prop

        S Offline
        S Offline
        sandro4912
        wrote on last edited by
        #3

        @LeLev Fixed it I actually used AspectFit. I only used Crop for testing. With fit it does not exceed the width but ignores the height of the rectangle

        1 Reply Last reply
        0
        • S Offline
          S Offline
          sandro4912
          wrote on last edited by
          #4

          One Idea I have:

          Is it possible to provide a minimum height to the view ?

          I know the width the delegate of the picture cell will have. Out of that I could calculate how much height the picture would need and maybe could supply it to the view?

          1 Reply Last reply
          0
          • fcarneyF Offline
            fcarneyF Offline
            fcarney
            wrote on last edited by
            #5

            @sandro4912 said in Calculate TableView height according to Image in delegate:

            PictureDelegate

            Are you setting the height of your PictureDelegate Item? Set that to the height of your picture.

            C++ is a perfectly valid school of magic.

            S 1 Reply Last reply
            0
            • fcarneyF fcarney

              @sandro4912 said in Calculate TableView height according to Image in delegate:

              PictureDelegate

              Are you setting the height of your PictureDelegate Item? Set that to the height of your picture.

              S Offline
              S Offline
              sandro4912
              wrote on last edited by sandro4912
              #6

              @fcarney

              I tried that but it freezes the app when I go to the picture:

              Item {
              //....
                  height: image.height // set height here
              
              //...
              
                  Image {
                      id: image
              
                      anchors.centerIn: parent
                      source: root.picture.length > 0 ? "data:image/png;base64," + root.picture : ""
                      fillMode: Image.PreserveAspectFit
                      sourceSize.width: rect.width - rect.border.width * 2
                      sourceSize.height: rect.height - rect.border.height * 2
                  }
              

              A solution I got via PM from @LeLev is omit soureSize complete and add width relative to parent width:

              Image {
                  id: image
              
                  width: parent.width - rect.border.width * 2
              
                  anchors.centerIn: parent
                  source: root.picture.length > 0 ? "data:image/png;base64," + root.picture : ""
                  fillMode: Image.PreserveAspectFit
              
                  Component.onCompleted: console.log(parent.width)
              }
              

              That works perflectly. It was just to simple to come up with it :(

              1 Reply Last reply
              0
              • S Offline
                S Offline
                sandro4912
                wrote on last edited by
                #7

                Unfortunately I was wrong even with the last approach I still have issues like this:

                f0c779c6-256b-455e-962e-2f028966b7d0-image.png

                Here the Image is again over the borders

                If you like to check the full code here:
                https://github.com/SandroWissmann/Quiz

                1 Reply Last reply
                0
                • fcarneyF Offline
                  fcarneyF Offline
                  fcarney
                  wrote on last edited by
                  #8
                  Image {
                          id: image
                  
                          anchors.centerIn: parent
                          source: root.picture.length > 0 ? "data:image/png;base64," + root.picture : ""
                          fillMode: Image.PreserveAspectFit
                          sourceSize.width: rect.width - rect.border.width * 2
                          sourceSize.height: rect.height - rect.border.height * 2
                      }
                  

                  Where do you set the height of your image? Not sourceSize.height, but height. sourceSize only affects memory allocation of the image.

                  C++ is a perfectly valid school of magic.

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    sandro4912
                    wrote on last edited by sandro4912
                    #9

                    @fcarney

                    I don't set the height I only provide the width from ListView.

                    The ListView should render to the maxHeight needed since heightWidthProvider is not set. So that all delegates can be displayed properly.

                    The solution to this issue Is replacing the root directly with the rectangle like this:

                    Rectangle {
                    //...
                       color: "transparent"
                       border.width: 1
                       border.color: "black"
                       id: root
                    
                       Image {
                           id: image
                    
                           anchors.fill: parent
                           anchors.margins: root.border.width
                           source: root.picture.length > 0 ? "data:image/png;base64," + root.picture : ""
                           fillMode: Image.PreserveAspectFit
                       }
                    
                    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