[solved]Tableview, listview or gridview?



  • I am still a qml beginner and I am looking for advice.
    I try to create something which looks similar to that:

    !http://s16.postimg.org/3y3i02d5h/explanatory_pix.png(explanatory pic)!

    Background info: I get the marks for each student in an xml-file and the values of the minimum column are computed from the c++ side and are variable. The coloring and the "all passed"-row are subsequently computed.

    However, I am struggling a bit...I don't really know which of the following would be the most appropriate:

    • tableview
    • listview
    • gridview

    Or is there something even more suited?
    Thank you in advance for any advice!



  • Hi,
    I think I would go for a "TableView":http://qt-project.org/doc/qt-5/qml-qtquick-controls-tableview.html as it seems the most appropriate to me for your needs.



  • Thank you for your advice!
    I am working with listview now, as I think it is more flexible (I wasn't able to figure out, how the orientation is changed in tableview).

    Now, I am facing a weird display issue: the listview/delegates overlap the borders of a groupbox and the window, unfortunately...see the lightgray delegate below:

    !http://s16.postimg.org/sld6qv8yd/pic_Boarder_Overlap.png(pic border overlap)!

    The part of the code where the listview is looks like that:

    @
    ListView {
    id: id_listView
    anchors.left: parent.left
    anchors.right: parent.right
    anchors.margins: 4
    height: headerItem.height //180

    spacing: 10
    orientation: Qt.Horizontal
    interactive: true
    boundsBehavior: Flickable.StopAtBounds
    
    focus: true
    
    header: myHeader
    delegate: contactDelegate
    model: id_xmlModel
    }
    

    @

    I couldn't find a fix to that. Do you have any ideas?
    Thank you very much!

    PS: Is there a way to specify the spacing between the header and the delegates? ...spacing only separates the delegates...



  • Hi,
    I don't know which item is the parent of the list view but it seems the width of list view is responsible for the overlapping. As a starting point, you can replace the list view by a rectangle and see if it also overlaps or not.
    If it's not a problem with the size of your list view,check the size of the delegates or try to add clipping (clip: true) to your list view.
    For header spacing, I usually play with header height and layout to get the desired space below the visible part of the header.



  • Awesome! Setting 'clip:true' solved it!
    And for the spacing of the header I now modified the header...thank you for the great hints!

    No I have two final questions:

    • Is there a way to make the header fixed? So only the delegates move and the header remains always visible/at the same position?

    • How can I add a scrollbar within the flickable? I tried to put a scrollview around the listview, however I got a 'binding loop error' with the following code:
      @
      ScrollView{
      id: id_scrollView
      anchors.left: parent.left
      anchors.right: parent.right
      //implicitHeight: 200
      implicitHeight: id_listView.height // binding loop :(

      ListView {
      id: id_listView

        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 4
        height: headerItem.height //180
        spacing: 10
        orientation: Qt.Horizontal
        interactive: true
        //boundsBehavior: Flickable.StopAtBounds
        
        focus: true
        clip: true        
        
        header: id_header
        //footer: id_footer
        delegate: id_delegate
        model: id_xmlModel       
      

      }
      }
      @
      I noticed that the bouncing behavior disappears when the listview is embedded in a scrollview.

    My goal is to create a list with a fixed header and a small scrollbar for the delegates.
    I am looking forward to your great advices!



  • The problem with the binding loop is that you are binding the ScrollView height to the ListView height. This is a loop because a ListView inside a ScrollView is implicitly bound to the height of the scrollView. What you want to do is to bind to the ListView.contentHeight which is the actual size of the listview contents.



  • Hi Jens, thank you for your answer!
    I am not really sure whether I understood your suggestion correctly. When I added the "implicitHeight: id_listView.contentHeight" in the scrollview, the displayed height was zero. The height of the listview is given by the height of the header in my horizontal list as you can see in the snippet:

    @
    ScrollView{
    id: id_scrollView
    anchors.left: parent.left
    anchors.right: parent.right
    implicitHeight: 240
    //implicitHeight: id_listView.contentHeight // suggested by jens => height of scrollview becomes zero
    //implicitHeight: id_listView.height // binding loop

    ListView {
        id: id_listView
        anchors.left: parent.left
        anchors.right: parent.right
        anchors.margins: 4 // if >0, scrollview crops the list from the right
        height: headerItem.height // is there another way to specify the height of the list?
    
        spacing: 10
        orientation: Qt.Horizontal
        interactive: true
    
        focus: true
        clip: true
    
        header: id_header
        delegate: id_delegate
        model: id_xmlModel
    
    }
    

    }
    @

    Do you have another suggestion? Or which part of your answer have I misunderstood?
    Also, I noticed, if I specify a anchors.margins in the listview, the scrollview crops the list from the right...
    In fact, I really like the flickable, I just would like to add a tiny, informative scrollbar and preferrably with a fixed header...how would you implement that?
    A huge thank you in advance!



  • I think this is what you might be looking for:

    @
    import QtQuick 2.0
    import QtQuick.Controls 1.1
    import QtQuick.Controls.Styles 1.1

    Rectangle {
    width: 360
    height: 360

    ScrollView {
        style: ScrollViewStyle { transientScrollBars: true }
        anchors.fill: parent
        ListView {
            model: 100
            delegate: Rectangle {
                color: "white"
                height: 20
                width: parent.width
                Label { text: "item " + index }
            }
            header: Rectangle {
                id: header
                color: "lightgray"
                height: 40
                width: parent.width
                Text { anchors.centerIn: parent ; text: "Header" }
            }
        }
    }
    

    }
    @



  • As for the fixed header (someone correct me if I'm wrong), I don't see another means of achieving what you want than removing the header from the list view and putting it in a separate item where you want it to show.



  • Sweet, the @style: ScrollViewStyle { transientScrollBars: true }@ is exactly what I was looking for! Thank you Jens!
    Now, for the "fixed" header I found a work-around, which I am quite satisfied with: I now use a section for all delegates :) In case you are interested, here is a minimal version:

    @
    import QtQuick 2.2
    import QtQuick.Controls 1.1
    import QtQuick.Controls.Styles 1.1
    import QtQuick.Layouts 1.1

    Rectangle {
    width: 250
    height: 150

    ListModel{
        id: myModel
        ListElement{ name: "Maria"; math: "11"; english: "7"; history: "12"; sectionDummy: "1" }
        ListElement{ name: "John"; math: "9"; english: "12"; history: "4"; sectionDummy: "1" }
        ListElement{ name: "Peter"; math: "14"; english: "5"; history: "18"; sectionDummy: "1" }
        ListElement{ name: "Lindsay"; math: "15"; english: "13"; history: "9"; sectionDummy: "1" }
    }
    
    Component{
        id: mySectionHeader
        Rectangle{
            height: myHeaderColLayout.height+20
            width: myHeaderColLayout.width+20
            color: "lightgray"; radius: 4
            ColumnLayout{
                id: myHeaderColLayout
                anchors.centerIn: parent
                Label { text: '<b>Name:</b> '}
                Label { text: '<b>Math:</b> '}
                Label { text: '<b>English:<b>' }
                Label { text: '<b>History:</b> ' }
            }
        }
    }
    
    Component{
        id: myDelegate
        Rectangle{
            height: myDelegateColLayout.height+20
            width: myDelegateColLayout.width+20
            ColumnLayout{
                id: myDelegateColLayout
                anchors.centerIn: parent
                Label{ text: '<b>' + name + '<b>'}
                Label{ text: math; anchors.horizontalCenter: parent.horizontalCenter}
                Label{ text: english; anchors.horizontalCenter: parent.horizontalCenter}
                Label{ text: history; anchors.horizontalCenter: parent.horizontalCenter}
            }
        }
    }
    
    ScrollView {
        id: myScrollView
        anchors.left: parent.left
        anchors.right: parent.right
        height: parent.height // is there a way to make the scrollview height fit to the listview height?
    

    // implicitHeight: myListView.height // doesn't work
    // implicitHeight: myListView.contentHeight // no luck either
    // implicitHeight: childrenRect.height // nope

        flickableItem.interactive: true
        style: ScrollViewStyle { transientScrollBars: true }
    
        ListView {
            id: myListView
            anchors.fill: parent
            orientation: Qt.Horizontal
            focus: true
            clip: true
            section.property: "sectionDummy"
            section.criteria: ViewSection.FullString
            section.delegate: mySectionHeader
            section.labelPositioning: ViewSection.CurrentLabelAtStart
            model: myModel
            delegate: myDelegate
        }
    }
    

    }
    @
    !http://s16.postimg.org/jl6r0r99h/snipped_look.png(image)!

    So, now the very last missing bit is: How can I make the height of the scrollview fit my listview? I tried several things, but had no luck so far (see above in the snipped). Also, Jens' earlier suggested 'implicitHeight: myListView.contentHeight' didn't work. Do you have some hints for me?
    Thank you for your great support!



  • I am actually puzzled that contentHeight is not set. However if you are trying to get childrenRect, you should do so on the contentItem as that is the paren t of your list items.

    I.e this should work:
    implicitHeight: myListView.contentItem.childrenRect.height

    But keep in mind that scroll bars don't generally float in the middle of the application window, so it might look better either to keep it at the bottom or draw a frame around the scroll view.



  • Thank you very much Jens, your suggestion works perfectly!
    Also, thank you for the hint with the frame around the scrollview...there are lots of things around now :)
    In case the contentHeight issue gets solved, I would be happy to know about it :)


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.