QML-ListView

雖然Qt是跨平臺的,但是桌面用戶和手機用戶的操作習慣存在很大的差異。手機用戶可以用手指直接滑動屏幕,而桌面用戶則必須藉助鼠標操作。在QML中,很多屬性的默認值都是優先考慮手機用戶的。如果使用默認值,在桌面軟件中就會覺得不習慣。所以在編寫桌面軟件時,ListView在使用時需要注意下列屬性:

interactive

此屬性的默認值是true,表示用戶可以拖動該對象。桌面軟件中應設置爲false。

clip

此屬性的默認值是false,表示不會自動截掉超出顯示區域的部分。桌面軟件中應設置爲true。


這樣設置後,如果顯示的內容超過了顯示區域,就必須爲ListView增加滾動條。用QML實現滾動條的方法,在Qt的例子(declarative/ui-components/scrollbar)裏有一個,可以參考修改。這個例子沒有實現拖動滾動條的功能,完善代碼如下,文件名爲ScrollBar.qml。

import QtQuick 1.1

Item  {
    id: container

    property variant scrollArea

    // orientation can be either Qt.Vertical or Qt.Horizontal
    property int orientation: Qt.Vertical

    opacity: 1.0

    // get button position
    function position()
    {
        var pos = 0;
        if (container.orientation === Qt.Vertical)
            pos = scrollArea.visibleArea.yPosition * (container.height-2) + 1;
        else
            pos = scrollArea.visibleArea.xPosition * (container.width-2) + 1;
        return pos;
    }

    // return button length
    function size()
    {
        var size;

        if (container.orientation === Qt.Vertical)
            size = scrollArea.visibleArea.heightRatio * (container.height-2);
        else
            size = scrollArea.visibleArea.widthRatio * (container.width-2);
        return size;
    }

    //background
    Rectangle  {
        id: bar
        anchors.fill: parent
        radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
        color: "black"
        opacity: 0.1
        Behavior on opacity {
            PropertyAnimation {
                duration: 100
                easing.type: Easing.InQuad
            }
        }
        //Scroll Button
        Rectangle {
            id: button
            x: orientation == Qt.Vertical ? 1 : position()
            y: orientation == Qt.Vertical ? position() : 1
            width: orientation == Qt.Vertical ? (parent.width-2) : size()
            height: orientation == Qt.Vertical ? size() : (parent.height-2)
            radius: orientation == Qt.Vertical ? (width/2 - 1) : (height/2 - 1)
            color: "black"
            opacity: 0.8

            MouseArea {
                id: ma_button
                anchors.fill: button
                hoverEnabled: true
                acceptedButtons: Qt.LeftButton
                drag.target: button
                drag.axis: Qt.Vertical ? Drag.YAxis : Drag.XAxis
                drag.minimumY: 0
                drag.maximumY: Qt.Vertical ? container.height - button.height : 0
                drag.minimumX: 0
                drag.maximumX: Qt.Vertical ? 0 : container.width - button.width

                // click button and drag
                onMouseYChanged: {
                    if(ma_button.pressed) {
                        scrollArea.contentY = button.y / container.height * scrollArea.contentHeight;
                    }
                }
                onEntered: {
                    bar.opacity = 0.3
                }
                onExited: {
                    bar.opacity = 0.1
                }
            }
        }
    }
}

在ListView中使用如下:

ListView {
    id: view_test
    ...
    interactive: false
    clip: true
}
ScrollBar  {
    scrollArea: view_test
    height: view_test.height
    width: 10
    anchors.right: view_test.right
}

ListView在顯示錶格時一般會顯示錶頭,我們會爲ListView指定一個header。這樣會導致一個問題,就是當拖動滾動條的時候,表頭不會鎖定,這一般不是我們所期望的,我們期望鎖定表頭。怎麼實現呢?這裏有一個小技巧,就是爲ListView指定一個什麼都不顯示的header,然後在ListView上面單獨放置一個表頭。我開始不指定header,結果滾動條雖然顯示正確,但是拖動距離無法限制,指定一個什麼都不顯示的header後,工作正常。什麼都不顯示的header如下:

Component {
    id: emptyHeader
    Rectangle {
        height: 0
        width: 0
    }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章