QML ListView实现多选操作

需求:

单击默认为单选,按住Ctrl+点击为任意项多选,按住Shift+点击为连续项多选

分析:

1.点击时区分按键状态来进行不同的操作;

2.根据不同的操作修改列表项的选中状态。

在Qt Widgets框架中,点击事件的QMouseEvent可以通过modifiers函数获取点击时按键的状态。在QML中,MouseArea的clicked(MouseEvent mouse)信号传递的MouseEvent也有这个modifiers属性,只要在点击时通过该属性判断哪些按键按下了就能把操作区分开来。

此外,选项状态的修改我是借助Connections关联信号槽来实现的。单选时,信号通知别的选项取消选中;Ctrl多选时直接选中不用发信号,各自独立选中;Shift多选时把起点行到点击行间的全选中。

实现:(简单的Demo如下)

QML ListView实现多选操作

//MyListView.qml
import QtQuick 2.12
import QtQuick.Controls 2.12

ListView {
    id: control

    //按住shift时,连续多选的起点
    property int mulBegin: 0
    //单选信号
    signal checkOne(int idx)
    //多选信号
    signal checkMul(int idx)

    Connections{
        target: control
        //单选时修改连选起点
        onCheckOne: control.mulBegin=idx;
    }

    //截取超出部分
    clip: true
    //不要橡皮筋效果
    boundsBehavior: Flickable.StopAtBounds
    //Item间隔
    spacing: 2

    model: 20
    delegate: Rectangle{
        id: item_delegate
        width: ListView.view.width
        height: 30
        //记录Item选中状态
        property bool checked: false
        border.color: "gray"
        color: item_delegate.checked? "black" : "gray"
        Connections{
            target: control
            onCheckOne: item_delegate.checked=(idx===index);
            onCheckMul: {
                //连续多选时,判断在起始点前还是后,然后把中间的选中
                if(idx>control.mulBegin){
                    item_delegate.checked=(index>=control.mulBegin&&index<=idx);
                }else{
                    item_delegate.checked=(index<=control.mulBegin&&index>=idx);
                }
            }
        }
        MouseArea{
            id: item_mousearea
            anchors.fill: parent
            onClicked: {
                //ctrl+多选,shift+连选,默认单选
                switch(mouse.modifiers){
                case Qt.ControlModifier:
                    item_delegate.checked=!item_delegate.checked;
                    break;
                case Qt.ShiftModifier:
                    control.checkMul(index);
                    break;
                default:
                    control.checkOne(index);
                    control.mulBegin=index;
                    break;
                }
            }
        }
    }

    ScrollBar.vertical: ScrollBar {
    }
}
//main.qml
import QtQuick 2.12
import QtQuick.Window 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("GongJianBo 1992")

    MyListView{
        anchors.fill: parent
        anchors.margins: 10
    }
}

 

上一篇:C#中的委托是什么


下一篇:Flutter:Slivers大家族,让滑动视图的组合变得很简单!