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. need ideas on styling a ListView
Forum Update on Monday, May 27th 2025

need ideas on styling a ListView

Scheduled Pinned Locked Moved Solved Brainstorm
27 Posts 4 Posters 4.5k 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.
  • JoeCFDJ JoeCFD

    @mzimmers I do not think that is a good idea. Delegates are made for rows. Your round corners are global settings.
    Normally you use alternative colors in listview(just like in tables) to display different rows. Pretty much standard practice. Therefore, no dividers are needed.

    jeremy_kJ Offline
    jeremy_kJ Offline
    jeremy_k
    wrote on last edited by
    #15

    @JoeCFD said in need ideas on styling a ListView:

    @mzimmers I do not think that is a good idea. Delegates are made for rows. Your round corners are global settings.

    DelegateChooser, explicit use of a Loader, or hiding/showing items that are always present are all viable techniques.

    Going this route, I might do something like:

    ListView {
        delegate: Rectangle {
            id: d
            Image {
                source: d.index == 0 ? topCorner
                        : d.index == (d.ListView.view.count - 1) ? bottomCorner
                        : undefined
            }
    }
    

    Normally you use alternative colors in listview(just like in tables) to display different rows. Pretty much standard practice. Therefore, no dividers are needed.

    That's a common design choice, but certainly not universal. Wanting a different appearance isn't unreasonable.

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

    1 Reply Last reply
    0
    • mzimmersM Offline
      mzimmersM Offline
      mzimmers
      wrote on last edited by
      #16

      I think I got it (sorry for the lengthy code include, but I wanted to show everything):

      // Roundlist.qml
      
      import QtQuick
      import QtQuick.Controls
      import QtQuick.Layouts
      
      Item {
          height: parent.height
          width: parent.width
      
          Rectangle {
              id: rect1
              property real rectRadius: 5.0
              property real rowHeight: 60.0
              property real rowSpacing: 3.0
      
              height: activityView.height + (rectRadius * 2)
              width: parent.width
              radius: rect1.rectRadius
              anchors {
                  horizontalCenter: parent.horizontalCenter
                  verticalCenter: parent.verticalCenter
              }
              color: 'white'
      
              Rectangle {
                  id: rect2
                  height: activityView.height
                  width: rect1.width
                  anchors.verticalCenter: rect1.verticalCenter
                  color: mainWindow.color
      
                  ListModel {
                      id: activityModel
                      ListElement { text: "aaa" }
                      ListElement { text: "bbb" }
                      ListElement { text: "ccc" }
                      ListElement { text: "ddd" }
                      ListElement { text: "eee" }
                  }
      
                  Component {
                      id: activityDelegate
                      Rectangle {
                          height: rect1.rowHeight
                          width: rect1.width
                          color: rect1.color
                          Text {
                              text: model.text
                              anchors {
                                  horizontalCenter: parent.horizontalCenter
                                  verticalCenter: parent.verticalCenter
                              }
                          }
                      }
                  }
      
                  ListView {
                      id: activityView
                      implicitHeight: contentItem.childrenRect.height
                      width: rect1.width
                      spacing: rect1.rowSpacing
                      clip: true
                      model: activityModel
                      delegate: activityDelegate
      
                  }
              }
          }
      }
      

      It works by itself, though I'm having problem embedding it in a ColumnLayout - instead of appearing inline, it overlays the other items. It should look something like this:
      good.PNG
      But it comes out like this (please ignore the different text in the rows):
      actual.PNG
      Here's how I'm trying to use it (heavily edited):

      Flickable {
      	id: flickable
      	Layout.fillHeight: true
      	Layout.fillWidth: true
      	clip: true
      	contentHeight: pumpStuff.height
      
      	ColumnLayout {
      		id: pumpStuff
      		height: parent.height
      		width: flickable.width - (scroller.width * 2)
      
      		RowLayout {
      			id: actions
      		}
      
      		Text {
      			id: parameters
      		}
      
      		Roundlist {}
      
      		RowLayout {
      			id: activities
      		}
      	}
      	ScrollBar.vertical: ScrollBar {
      		id: scroller
      		policy: ScrollBar.AlwaysOn//AsNeeded
      	}
      }
      

      Any idea why this is happening?

      Thanks...

      jeremy_kJ 2 Replies Last reply
      0
      • mzimmersM mzimmers

        I think I got it (sorry for the lengthy code include, but I wanted to show everything):

        // Roundlist.qml
        
        import QtQuick
        import QtQuick.Controls
        import QtQuick.Layouts
        
        Item {
            height: parent.height
            width: parent.width
        
            Rectangle {
                id: rect1
                property real rectRadius: 5.0
                property real rowHeight: 60.0
                property real rowSpacing: 3.0
        
                height: activityView.height + (rectRadius * 2)
                width: parent.width
                radius: rect1.rectRadius
                anchors {
                    horizontalCenter: parent.horizontalCenter
                    verticalCenter: parent.verticalCenter
                }
                color: 'white'
        
                Rectangle {
                    id: rect2
                    height: activityView.height
                    width: rect1.width
                    anchors.verticalCenter: rect1.verticalCenter
                    color: mainWindow.color
        
                    ListModel {
                        id: activityModel
                        ListElement { text: "aaa" }
                        ListElement { text: "bbb" }
                        ListElement { text: "ccc" }
                        ListElement { text: "ddd" }
                        ListElement { text: "eee" }
                    }
        
                    Component {
                        id: activityDelegate
                        Rectangle {
                            height: rect1.rowHeight
                            width: rect1.width
                            color: rect1.color
                            Text {
                                text: model.text
                                anchors {
                                    horizontalCenter: parent.horizontalCenter
                                    verticalCenter: parent.verticalCenter
                                }
                            }
                        }
                    }
        
                    ListView {
                        id: activityView
                        implicitHeight: contentItem.childrenRect.height
                        width: rect1.width
                        spacing: rect1.rowSpacing
                        clip: true
                        model: activityModel
                        delegate: activityDelegate
        
                    }
                }
            }
        }
        

        It works by itself, though I'm having problem embedding it in a ColumnLayout - instead of appearing inline, it overlays the other items. It should look something like this:
        good.PNG
        But it comes out like this (please ignore the different text in the rows):
        actual.PNG
        Here's how I'm trying to use it (heavily edited):

        Flickable {
        	id: flickable
        	Layout.fillHeight: true
        	Layout.fillWidth: true
        	clip: true
        	contentHeight: pumpStuff.height
        
        	ColumnLayout {
        		id: pumpStuff
        		height: parent.height
        		width: flickable.width - (scroller.width * 2)
        
        		RowLayout {
        			id: actions
        		}
        
        		Text {
        			id: parameters
        		}
        
        		Roundlist {}
        
        		RowLayout {
        			id: activities
        		}
        	}
        	ScrollBar.vertical: ScrollBar {
        		id: scroller
        		policy: ScrollBar.AlwaysOn//AsNeeded
        	}
        }
        

        Any idea why this is happening?

        Thanks...

        jeremy_kJ Offline
        jeremy_kJ Offline
        jeremy_k
        wrote on last edited by
        #17

        Unexpected overlapping is frequently a lack of sizing in the outermost item in a component. Eg:

        Item {
            Rectangle { width: 100; height: 100 }
        }
        

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

        1 Reply Last reply
        0
        • mzimmersM mzimmers

          I think I got it (sorry for the lengthy code include, but I wanted to show everything):

          // Roundlist.qml
          
          import QtQuick
          import QtQuick.Controls
          import QtQuick.Layouts
          
          Item {
              height: parent.height
              width: parent.width
          
              Rectangle {
                  id: rect1
                  property real rectRadius: 5.0
                  property real rowHeight: 60.0
                  property real rowSpacing: 3.0
          
                  height: activityView.height + (rectRadius * 2)
                  width: parent.width
                  radius: rect1.rectRadius
                  anchors {
                      horizontalCenter: parent.horizontalCenter
                      verticalCenter: parent.verticalCenter
                  }
                  color: 'white'
          
                  Rectangle {
                      id: rect2
                      height: activityView.height
                      width: rect1.width
                      anchors.verticalCenter: rect1.verticalCenter
                      color: mainWindow.color
          
                      ListModel {
                          id: activityModel
                          ListElement { text: "aaa" }
                          ListElement { text: "bbb" }
                          ListElement { text: "ccc" }
                          ListElement { text: "ddd" }
                          ListElement { text: "eee" }
                      }
          
                      Component {
                          id: activityDelegate
                          Rectangle {
                              height: rect1.rowHeight
                              width: rect1.width
                              color: rect1.color
                              Text {
                                  text: model.text
                                  anchors {
                                      horizontalCenter: parent.horizontalCenter
                                      verticalCenter: parent.verticalCenter
                                  }
                              }
                          }
                      }
          
                      ListView {
                          id: activityView
                          implicitHeight: contentItem.childrenRect.height
                          width: rect1.width
                          spacing: rect1.rowSpacing
                          clip: true
                          model: activityModel
                          delegate: activityDelegate
          
                      }
                  }
              }
          }
          

          It works by itself, though I'm having problem embedding it in a ColumnLayout - instead of appearing inline, it overlays the other items. It should look something like this:
          good.PNG
          But it comes out like this (please ignore the different text in the rows):
          actual.PNG
          Here's how I'm trying to use it (heavily edited):

          Flickable {
          	id: flickable
          	Layout.fillHeight: true
          	Layout.fillWidth: true
          	clip: true
          	contentHeight: pumpStuff.height
          
          	ColumnLayout {
          		id: pumpStuff
          		height: parent.height
          		width: flickable.width - (scroller.width * 2)
          
          		RowLayout {
          			id: actions
          		}
          
          		Text {
          			id: parameters
          		}
          
          		Roundlist {}
          
          		RowLayout {
          			id: activities
          		}
          	}
          	ScrollBar.vertical: ScrollBar {
          		id: scroller
          		policy: ScrollBar.AlwaysOn//AsNeeded
          	}
          }
          

          Any idea why this is happening?

          Thanks...

          jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by jeremy_k
          #18

          @mzimmers said in need ideas on styling a ListView:

          I think I got it (sorry for the lengthy code include, but I wanted to show everything):

          // Roundlist.qml
          
          import QtQuick
          import QtQuick.Controls
          import QtQuick.Layouts
          
          Item {
              height: parent.height
              width: parent.width
          

          As a style guide, never reference parent or anything outside of the component. Let the instantiator impose its constraints. Use implicitWidth and implicitHeight to specify reasonable defaults.

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

          mzimmersM 1 Reply Last reply
          1
          • TomZT Offline
            TomZT Offline
            TomZ
            wrote on last edited by
            #19

            Apologies if this is answered, I only read the first 2 posts of this long topic.

            I worked on something very similar just last month and the QML is really simple. (full).

            delegate: Item {
              height: 80
              clip: true
              Rectangle {
                // we always have the rounded circles, but if we should not see them, 
                // we move them out of the clipped area.
                height: {
                     var h = 80;
                     if (index == 0)
                         h += 20
                     if (index == MAX) // donno, bottom check.
                        h += 20
                    return h;
                  }
                  radius: 20
                  y: index == 0 ? 0 : -20
              }
            }
            mzimmersM 1 Reply Last reply
            1
            • jeremy_kJ jeremy_k

              @mzimmers said in need ideas on styling a ListView:

              I think I got it (sorry for the lengthy code include, but I wanted to show everything):

              // Roundlist.qml
              
              import QtQuick
              import QtQuick.Controls
              import QtQuick.Layouts
              
              Item {
                  height: parent.height
                  width: parent.width
              

              As a style guide, never reference parent or anything outside of the component. Let the instantiator impose its constraints. Use implicitWidth and implicitHeight to specify reasonable defaults.

              mzimmersM Offline
              mzimmersM Offline
              mzimmers
              wrote on last edited by
              #20

              @jeremy_k said in need ideas on styling a ListView:

              As a style guide, never reference parent or anything outside of the component. Let the instantiator impose its constraints. Use implicitWidth and implicitHeight to specify reasonable defaults.

              Understood. How do you handle a case where the instantiator doesn't know the height, because (for example) there might be a variable number of rows? I'm hoping to make this reusable.

              jeremy_kJ 1 Reply Last reply
              0
              • mzimmersM mzimmers

                @jeremy_k said in need ideas on styling a ListView:

                As a style guide, never reference parent or anything outside of the component. Let the instantiator impose its constraints. Use implicitWidth and implicitHeight to specify reasonable defaults.

                Understood. How do you handle a case where the instantiator doesn't know the height, because (for example) there might be a variable number of rows? I'm hoping to make this reusable.

                jeremy_kJ Offline
                jeremy_kJ Offline
                jeremy_k
                wrote on last edited by jeremy_k
                #21

                @mzimmers said in need ideas on styling a ListView:

                @jeremy_k said in need ideas on styling a ListView:

                As a style guide, never reference parent or anything outside of the component. Let the instantiator impose its constraints. Use implicitWidth and implicitHeight to specify reasonable defaults.

                Understood. How do you handle a case where the instantiator doesn't know the height, because (for example) there might be a variable number of rows? I'm hoping to make this reusable.

                implicitHeight:

                If width or height is not specified, an item's effective size will be determined by its implicitWidth or implicitHeight.

                However, if an item is the child of a layout, the layout will determine the item's preferred size using its implicit size. In such a scenario, the explicit width or height will be ignored.

                The default implicit size for most items is 0x0, however some items have an inherent implicit size which cannot be overridden, for example, Image and Text.

                Setting the implicit size is useful for defining components that have a preferred size based on their content

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

                mzimmersM 1 Reply Last reply
                0
                • jeremy_kJ jeremy_k

                  @mzimmers said in need ideas on styling a ListView:

                  @jeremy_k said in need ideas on styling a ListView:

                  As a style guide, never reference parent or anything outside of the component. Let the instantiator impose its constraints. Use implicitWidth and implicitHeight to specify reasonable defaults.

                  Understood. How do you handle a case where the instantiator doesn't know the height, because (for example) there might be a variable number of rows? I'm hoping to make this reusable.

                  implicitHeight:

                  If width or height is not specified, an item's effective size will be determined by its implicitWidth or implicitHeight.

                  However, if an item is the child of a layout, the layout will determine the item's preferred size using its implicit size. In such a scenario, the explicit width or height will be ignored.

                  The default implicit size for most items is 0x0, however some items have an inherent implicit size which cannot be overridden, for example, Image and Text.

                  Setting the implicit size is useful for defining components that have a preferred size based on their content

                  mzimmersM Offline
                  mzimmersM Offline
                  mzimmers
                  wrote on last edited by mzimmers
                  #22

                  @jeremy_k I see. So, this seems to work:

                  StackLayout {
                  
                      Home {}
                      Equipment {}
                      Rectangle {
                          Layout.fillHeight: true
                          Layout.fillWidth: true
                  
                          Roundlist {
                              width: parent.width
                          }
                      }
                  }
                  
                  // Roundlist.qml
                  Item {
                      implicitHeight: activityView.height + (rect1.rectRadius * 2)
                      ...
                  

                  And I can live with this, though it seems weird to set the height in once place, and the width in another. Is there a cleaner way to do this?

                  jeremy_kJ 1 Reply Last reply
                  0
                  • TomZT TomZ

                    Apologies if this is answered, I only read the first 2 posts of this long topic.

                    I worked on something very similar just last month and the QML is really simple. (full).

                    delegate: Item {
                      height: 80
                      clip: true
                      Rectangle {
                        // we always have the rounded circles, but if we should not see them, 
                        // we move them out of the clipped area.
                        height: {
                             var h = 80;
                             if (index == 0)
                                 h += 20
                             if (index == MAX) // donno, bottom check.
                                h += 20
                            return h;
                          }
                          radius: 20
                          y: index == 0 ? 0 : -20
                      }
                    }
                    mzimmersM Offline
                    mzimmersM Offline
                    mzimmers
                    wrote on last edited by
                    #23

                    @TomZ thanks for the reply. I think I prefer my implementation for my particular purposes, but I like elements of yours as well.

                    1 Reply Last reply
                    1
                    • mzimmersM mzimmers

                      @jeremy_k I see. So, this seems to work:

                      StackLayout {
                      
                          Home {}
                          Equipment {}
                          Rectangle {
                              Layout.fillHeight: true
                              Layout.fillWidth: true
                      
                              Roundlist {
                                  width: parent.width
                              }
                          }
                      }
                      
                      // Roundlist.qml
                      Item {
                          implicitHeight: activityView.height + (rect1.rectRadius * 2)
                          ...
                      

                      And I can live with this, though it seems weird to set the height in once place, and the width in another. Is there a cleaner way to do this?

                      jeremy_kJ Offline
                      jeremy_kJ Offline
                      jeremy_k
                      wrote on last edited by
                      #24

                      @mzimmers said in need ideas on styling a ListView:

                      And I can live with this, though it seems weird to set the height in once place, and the width in another. Is there a cleaner way to do this?

                      The component can set implicitWidth as well, and probably should. Otherwise you might end up with a 0-width item that renders correctly on its own, but is overlapped when used in a row layout of some form.

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

                      mzimmersM 1 Reply Last reply
                      0
                      • jeremy_kJ jeremy_k

                        @mzimmers said in need ideas on styling a ListView:

                        And I can live with this, though it seems weird to set the height in once place, and the width in another. Is there a cleaner way to do this?

                        The component can set implicitWidth as well, and probably should. Otherwise you might end up with a 0-width item that renders correctly on its own, but is overlapped when used in a row layout of some form.

                        mzimmersM Offline
                        mzimmersM Offline
                        mzimmers
                        wrote on last edited by
                        #25

                        @jeremy_k said in need ideas on styling a ListView:

                        The component can set implicitWidth as well, and probably should.

                        I'll do that -- just wondering whether there was any way to derive a value from the caller. But I guess the width value is just that, so...that's what I'll use. I'll just pick some value for the implicitWidth that hopefully will never get used.

                        Thanks for all the help...I think I'm done with this one.

                        1 Reply Last reply
                        0
                        • jeremy_kJ Offline
                          jeremy_kJ Offline
                          jeremy_k
                          wrote on last edited by
                          #26

                          FontMetrics could provide an implicitWidth value based on the model's data. I presume that Text does something similar.

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

                          1 Reply Last reply
                          0
                          • mzimmersM Offline
                            mzimmersM Offline
                            mzimmers
                            wrote on last edited by
                            #27

                            For anyone who might be reading this for an answer to their own question, I looked at @TomZ 's solution, and realized that I had a bug in my delegate - my text centering wasn't taking the rounded corners effectively adding height to the top and bottom rows. I had to alter my delegate:

                            Component {
                                id: activityDelegate
                                Rectangle {
                                    height: {
                                        var h = rect1.rowHeight;
                                        if (index === 0 || index === (activityModel.count - 1))
                                            h -= rect1.radius
                                        return h;
                                    }
                                    width: rect1.width
                                    color: rect1.color
                                    Text {
                                        text: model.parameter
                                        anchors {
                                            left: parent.left
                                            leftMargin: parent.height / 2
                                            verticalCenter: parent.verticalCenter
                                            verticalCenterOffset: {
                                                var o = 0;
                                                if (index === 0)
                                                    o -= (radius / 2)
                                                else if (index === (activityModel.count - 1))
                                                    o += (radius / 2)
                                                return o;
                                            }
                                        }
                            
                                        font.pixelSize: 14
                                        font.bold: true
                                    }
                                    Styledswitch {
                                        id: onOff
                                        visible: model.switchVisible
                                        anchors {
                                            right: parent.right
                                            rightMargin: parent.height / 2
                                            verticalCenter: parent.verticalCenter
                                        }
                                    }
                                }
                            }
                            

                            As always, if this doesn't look right, please let me know, and I'll fix it.

                            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