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
    }
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值