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. Row of Text items in ListView
Forum Updated to NodeBB v4.3 + New Features

Row of Text items in ListView

Scheduled Pinned Locked Moved Solved QML and Qt Quick
18 Posts 4 Posters 3.1k 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.
  • B Offline
    B Offline
    Bob64
    wrote on last edited by Bob64
    #1

    I currently have a ListView with its delegate being a simple Text item. The list is meant to display a set of messages generated by the application. The messages are generally of unpredictable length. However, by setting the text width to the ListView width, and setting wrapping on, each list element adjusts its height to the text without me having to do any more work. It is essential that I preserve this behaviour.

    I would now like to introduce another Text element into the list delegate. This is actually to hold one of a number of icons that are available to me in a custom font. As such, this Text element just holds a single character and has a predictable size. The idea is that the icon text should be to the left of the main message Text item. I implemented this using a Row, setting its height to be the maximum of the content height of the icon Text element and the message Text element.

    This seems to work, except that I now want to introduce a MouseArea to the list row, to allow the row to be selected. If I parent it to the Row, the layout of the Text items is screwed up (the icon overlaps the message). If I parent it to the message element, it works, but then clicking on the icon to select the row does not work.

    I can sort of solve it by adding a separate MouseArea to the icon Text but not only does this seem a little clunky but I also have a dead spot in the spacing between the row elements. There is probably a way around it by eliminating the spacing and embedding the space into one of the text items instead but in my quest to understand QML better I am wondering if there is a better way to do things that allows me to specify a single MouseArea but still gets the sizing and layout right etc.

    The most relevant code is below:

            ListView {
                id: messageList
    
                anchors.fill: parent
                anchors.margins: 5
                model: messageModel // has fields 'message' and 'level'
                spacing: 5
    
                delegate: Row {
                    width: root.width
                    height: Math.max(iconText.contentHeight, msgText.contentHeight)
                    spacing: 5
                    Text {
                        id: iconText
                        text: iconText(level)
                        color: iconColor(level)
                        font.family: msgIconsFont.name
                        font.pointSize: 15
                        MouseArea {
                            anchors.fill: parent
                            onClicked: errorList.currentIndex = index
                        }
                    }
                    Text {
                        id: msgTxt
                        text: message
                        width: root.width - iconText.width - parent.spacing
                        wrapMode: Text.Wrap
                        MouseArea {
                            anchors.fill: parent
                            onClicked: messageList.currentIndex = index
                        }
                    }
                }
               ...
    
    1 Reply Last reply
    0
    • B Bob64

      @GrecKo Thank you so much for your help but it seems implicitContentHeight is not available in my version of Qt.

      IntruderExcluderI Offline
      IntruderExcluderI Offline
      IntruderExcluder
      wrote on last edited by
      #17

      @Bob64 said in Row of Text items in ListView:

      @GrecKo Thank you so much for your help but it seems implicitContentHeight is not available in my version of Qt.

      Use implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding then.

      B 1 Reply Last reply
      1
      • B Offline
        B Offline
        Bob64
        wrote on last edited by
        #2

        OK, so I have realised that the problem with parenting the MouseArea to the Row is that it is not possible to use the fill anchor in that context.

        So I guess the question simplifies to: how does one specify a MouseArea for a Row?

        ODБOïO 1 Reply Last reply
        0
        • B Bob64

          OK, so I have realised that the problem with parenting the MouseArea to the Row is that it is not possible to use the fill anchor in that context.

          So I guess the question simplifies to: how does one specify a MouseArea for a Row?

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

          @Bob64 said in Row of Text items in ListView:

          fill anchor in that context.

          you can simply set height and width to fill the row

            Row{
                id:row
              anchors.fill: parent
              MouseArea{
                  //anchors.fill: parent
                  height: row.height
                  width: row.width
                  onClicked: console.log("click")
              }
            }
          
          B 1 Reply Last reply
          0
          • ODБOïO ODБOï

            @Bob64 said in Row of Text items in ListView:

            fill anchor in that context.

            you can simply set height and width to fill the row

              Row{
                  id:row
                anchors.fill: parent
                MouseArea{
                    //anchors.fill: parent
                    height: row.height
                    width: row.width
                    onClicked: console.log("click")
                }
              }
            
            B Offline
            B Offline
            Bob64
            wrote on last edited by
            #4

            @LeLev Thanks - that does seem like an obvious solution! Unfortunately, something isn't right, as selection is no longer working.

            1 Reply Last reply
            0
            • GrecKoG Offline
              GrecKoG Offline
              GrecKo
              Qt Champions 2018
              wrote on last edited by
              #5

              You could put the MouseArea as the parent of the Row, it would be less ugly than making the width of an Item (your MouseArea) in a Row depending on the row's width, while the Row's width depends on its children's width...

              Alternatively you could use a TapHandler which is not an Item.

              Your manual handling of width in a container could also be avoided if you were to use a Layout

              I would write your delegate like that:

              RowLayout {
                  width: root.width
                  spacing: 5
                  Text {
                      text: iconText(level)
                      color: iconColor(level)
                      font {
                          family: msgIconsFont.name
                          pointSize: 15
                       }
                  }
                  Text {
                      text: message
                      Layout.fillWidth: true
                      wrapMode: Text.Wrap
                  }
                  TapHandler{
                      onTapped: messageList.currentIndex = index
                  }
              }
              
              1 Reply Last reply
              2
              • IntruderExcluderI Offline
                IntruderExcluderI Offline
                IntruderExcluder
                wrote on last edited by
                #6

                The best way is to use ItemDelegate as delegate for ListView from QtQuick.Controls 2 with Row or RowLayout as contentItem and listen onClicked signal.

                1 Reply Last reply
                3
                • B Offline
                  B Offline
                  Bob64
                  wrote on last edited by Bob64
                  #7

                  Thanks - some ideas to try there.

                  Couple of notes:

                  1. TapHandler doesn't appear to be available in the version of Qt I am currently constrained to use (5.9.6).
                  2. Although I have ended up using RowLayout (and SplitView and such like) in some other places I always try to avoid QTQuick 1 dependencies if possible. Am I being unreasonable? Are layouts one of those things that are completely OK to mix with QtQuick 2?
                  1 Reply Last reply
                  0
                  • IntruderExcluderI Offline
                    IntruderExcluderI Offline
                    IntruderExcluder
                    wrote on last edited by
                    #8

                    While Layouts are importing looks like 1.x this doesn't means that they are from Quick 1, it is because of weird versioning in QML. The one thing you should avoid is QuickControls 1.x since they are deprecated at least (and also ugly and slow).

                    B 1 Reply Last reply
                    0
                    • IntruderExcluderI IntruderExcluder

                      While Layouts are importing looks like 1.x this doesn't means that they are from Quick 1, it is because of weird versioning in QML. The one thing you should avoid is QuickControls 1.x since they are deprecated at least (and also ugly and slow).

                      B Offline
                      B Offline
                      Bob64
                      wrote on last edited by
                      #9

                      @IntruderExcluder Understood. Unfortunately I do have to use SplitView and TreeView from Controls 1 as there are no alternatives.

                      GrecKoG 1 Reply Last reply
                      0
                      • B Bob64

                        @IntruderExcluder Understood. Unfortunately I do have to use SplitView and TreeView from Controls 1 as there are no alternatives.

                        GrecKoG Offline
                        GrecKoG Offline
                        GrecKo
                        Qt Champions 2018
                        wrote on last edited by
                        #10

                        @Bob64 There is a SplitView in Qt Quick Controls 2 since Qt 5.13

                        B 1 Reply Last reply
                        0
                        • GrecKoG GrecKo

                          @Bob64 There is a SplitView in Qt Quick Controls 2 since Qt 5.13

                          B Offline
                          B Offline
                          Bob64
                          wrote on last edited by Bob64
                          #11

                          @GrecKo unfortunately I am stuck on 5.9.6 for the time being. Also, judging by some of the questions in this forum, it looks like the new SplitView isn't quite ready for production use yet anyway.

                          1 Reply Last reply
                          0
                          • B Offline
                            B Offline
                            Bob64
                            wrote on last edited by
                            #12

                            I think I have tried out all of the possible ideas in this thread but they all fail in one way or another. Either they are not available to me in Qt 5.9.6, or the text stops wrapping, or the mouse area stops capturing the list item selection, or the list row heights become a uniform height rather than each one adjusting itself according to its text. This last behaviour is something that is essential for me to preserve. The best I have been able to come up with is a variation on my original code with two separate mouse areas. To avoid the small dead spot in the space between row items, I have set the spacing to 0 and instead added a leftMargin to the Text item.

                            GrecKoG 1 Reply Last reply
                            0
                            • B Bob64

                              I think I have tried out all of the possible ideas in this thread but they all fail in one way or another. Either they are not available to me in Qt 5.9.6, or the text stops wrapping, or the mouse area stops capturing the list item selection, or the list row heights become a uniform height rather than each one adjusting itself according to its text. This last behaviour is something that is essential for me to preserve. The best I have been able to come up with is a variation on my original code with two separate mouse areas. To avoid the small dead spot in the space between row items, I have set the spacing to 0 and instead added a leftMargin to the Text item.

                              GrecKoG Offline
                              GrecKoG Offline
                              GrecKo
                              Qt Champions 2018
                              wrote on last edited by
                              #13

                              @Bob64 said in Row of Text items in ListView:

                              I think I have tried out all of the possible ideas in this thread but they all fail in one way or another. Either they are not available to me in Qt 5.9.6, or the text stops wrapping, or the mouse area stops capturing the list item selection, or the list row heights become a uniform height rather than each one adjusting itself according to its text.

                              IntruderExcluder's solution should work:

                              import QtQuick 2.0
                              import QtQuick.Window 2.0
                              import QtQuick.Controls 2.0
                              import QtQuick.Layouts 1.0
                              
                              Window {
                                  id: root
                                  visible: true
                                  width: 640
                                  height: 480
                                  title: qsTr("Hello World")
                              
                                  ListModel {
                                      id: messageModel
                                      ListElement {
                                          message: "sadasdasdad"
                                          level: 1
                                      }
                                      ListElement {
                                          message: "sadasdaasdasdasdasdasdad"
                                          level: 2
                                      }
                                      ListElement {
                                          message: "sadasdaasdasdqweqweqwesdad"
                                          level: 3
                                      }
                                      ListElement {
                                          message: "sadasdarwerwerwerwerwerwerwerwerwesdadsadasdarwerwerwerwerwerwerwerwerwesdad"
                                          level: 4
                                      }
                                  }
                              
                                  ListView {
                                      anchors.fill: parent
                                      model: messageModel
                              
                                      delegate: ItemDelegate {
                                          width: root.width
                                          padding: 5
                                          contentItem: RowLayout {
                                              spacing: 5
                                              Text {
                                                  text: model.level
                                              }
                                              Text {
                                                  text: model.message
                                                  Layout.fillWidth: true
                                                  wrapMode: Text.Wrap
                                              }
                                          }
                                          onClicked: print(model.index)
                                      }
                                  }
                              }
                              
                              B 1 Reply Last reply
                              1
                              • GrecKoG GrecKo

                                @Bob64 said in Row of Text items in ListView:

                                I think I have tried out all of the possible ideas in this thread but they all fail in one way or another. Either they are not available to me in Qt 5.9.6, or the text stops wrapping, or the mouse area stops capturing the list item selection, or the list row heights become a uniform height rather than each one adjusting itself according to its text.

                                IntruderExcluder's solution should work:

                                import QtQuick 2.0
                                import QtQuick.Window 2.0
                                import QtQuick.Controls 2.0
                                import QtQuick.Layouts 1.0
                                
                                Window {
                                    id: root
                                    visible: true
                                    width: 640
                                    height: 480
                                    title: qsTr("Hello World")
                                
                                    ListModel {
                                        id: messageModel
                                        ListElement {
                                            message: "sadasdasdad"
                                            level: 1
                                        }
                                        ListElement {
                                            message: "sadasdaasdasdasdasdasdad"
                                            level: 2
                                        }
                                        ListElement {
                                            message: "sadasdaasdasdqweqweqwesdad"
                                            level: 3
                                        }
                                        ListElement {
                                            message: "sadasdarwerwerwerwerwerwerwerwerwesdadsadasdarwerwerwerwerwerwerwerwerwesdad"
                                            level: 4
                                        }
                                    }
                                
                                    ListView {
                                        anchors.fill: parent
                                        model: messageModel
                                
                                        delegate: ItemDelegate {
                                            width: root.width
                                            padding: 5
                                            contentItem: RowLayout {
                                                spacing: 5
                                                Text {
                                                    text: model.level
                                                }
                                                Text {
                                                    text: model.message
                                                    Layout.fillWidth: true
                                                    wrapMode: Text.Wrap
                                                }
                                            }
                                            onClicked: print(model.index)
                                        }
                                    }
                                }
                                
                                B Offline
                                B Offline
                                Bob64
                                wrote on last edited by
                                #14

                                @GrecKo Thank you. That is almost there. For longer text items, the rows will adjust their height as required. However the default height of each row makes the list too spaced out for brief text items (seems to default to 40 for me). This seems like it should be a simple tweak but I haven't been able to find it yet!

                                1 Reply Last reply
                                0
                                • GrecKoG Offline
                                  GrecKoG Offline
                                  GrecKo
                                  Qt Champions 2018
                                  wrote on last edited by
                                  #15

                                  That's because the implicitHeight of the ItemDelegate is based on the max of the one from its background and its contentItem.

                                  You can ignore the background implicitHeight by adding: implicitHeight: implicitContentHeight + topPadding + bottomPadding

                                  B 1 Reply Last reply
                                  1
                                  • GrecKoG GrecKo

                                    That's because the implicitHeight of the ItemDelegate is based on the max of the one from its background and its contentItem.

                                    You can ignore the background implicitHeight by adding: implicitHeight: implicitContentHeight + topPadding + bottomPadding

                                    B Offline
                                    B Offline
                                    Bob64
                                    wrote on last edited by
                                    #16

                                    @GrecKo Thank you so much for your help but it seems implicitContentHeight is not available in my version of Qt.

                                    IntruderExcluderI 1 Reply Last reply
                                    0
                                    • B Bob64

                                      @GrecKo Thank you so much for your help but it seems implicitContentHeight is not available in my version of Qt.

                                      IntruderExcluderI Offline
                                      IntruderExcluderI Offline
                                      IntruderExcluder
                                      wrote on last edited by
                                      #17

                                      @Bob64 said in Row of Text items in ListView:

                                      @GrecKo Thank you so much for your help but it seems implicitContentHeight is not available in my version of Qt.

                                      Use implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding then.

                                      B 1 Reply Last reply
                                      1
                                      • IntruderExcluderI IntruderExcluder

                                        @Bob64 said in Row of Text items in ListView:

                                        @GrecKo Thank you so much for your help but it seems implicitContentHeight is not available in my version of Qt.

                                        Use implicitHeight: contentItem.implicitHeight + topPadding + bottomPadding then.

                                        B Offline
                                        B Offline
                                        Bob64
                                        wrote on last edited by
                                        #18

                                        @IntruderExcluder Thank you! I thought I had tried that one but obviously not. Anyway, it works well. Thank you for this and for your original suggestion.

                                        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