QML制作可拖动添加项目&交换listview项目顺序的工具条

树形层listview(内层是Repeater,多层的话添加Repeater中的Repeater即可)

拖动交换index得实现(通过MouseArea获取鼠标事件操作model)
将其放入Delegate中即可

MouseArea{
            id: mousearea
            anchors.fill: parent;
            onClicked: {
                editList.currentIndex = index;
            }
            onPressed: {
                editList.currentIndex = index;
                dele.fromIndex = index;
                editList.isClicked = true;
                
            }
            onReleased: {
                editList.isClicked = false;
                console.log("fromIndex:", dele.fromIndex, "toIndex:", dele.toIndex);
            }
            onPositionChanged: {
                var lastIndex = editList.indexAt(mouseX + dele.x, mouseY + dele.y);
                if ((lastIndex < 0) || (lastIndex > dataModel.rowCount()))
                    return ;
                if (index !== lastIndex){
                    dataModel.move(index, lastIndex, 1);
                }
                dele.toIndex = lastIndex;
            }
            onPressAndHold: dataModel.remove(index);
        } 
  1. main.qml
import QtQuick 2.12
import QtQuick.Controls 2.5
ApplicationWindow{
    id: root;
    visible: true;
    color: "white";
    width: 500;
    height: 640;
    DragableToolbar{
        id: bar;
        anchors.right: parent.right;
        height: parent.height;
    }
    ToolBox {
        id: tool;
        height: parent.height;
        width: 200;
        anchors.left: parent.left;
    }
}
  1. DragableToolbar.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
import QtQuick.Layouts 1.12

ListView{
    id: editList;
    width: 200;
    height: parent.height;
    property bool isClicked: false;
    interactive: !isClicked;
    spacing: 5;
    
    flickableDirection: Flickable.VerticalFlick;
    boundsBehavior: Flickable.StopAtBounds;
    ScrollBar.vertical: ScrollBar {id:scrollBar;active: true;}
    Keys.onUpPressed: scrollBar.decrease();
    Keys.onDownPressed: scrollBar.increase();
    move: Transition {
        NumberAnimation{
            properties: "x,y";
            duration: 200;
            easing.type: Easing.OutQuart;
        }
    }
    
    model: ListModel{
        id: dataModel;
        ListElement{ string: "图像采集"; toolNumber: 0 }
        ListElement{ string: "图像预处理"; toolNumber: 0 }
    }
    
    delegate: Rectangle{
        id: dele;
        width: parent.width;
        height: 30;
        property int fromIndex: 0;
        property int toIndex: 0;
        color: "lightblue";
        Text {
            id: deleText;
            text: string;
            anchors.centerIn: parent;
        }
        MouseArea{
            id: mousearea
            anchors.fill: parent;
            onClicked: {
                editList.currentIndex = index;
            }
            onPressed: {
                editList.currentIndex = index;
                dele.fromIndex = index;
                editList.isClicked = true;
                
            }
            onReleased: {
                editList.isClicked = false;
                console.log("fromIndex:", dele.fromIndex, "toIndex:", dele.toIndex);
            }
            onPositionChanged: {
                var lastIndex = editList.indexAt(mouseX + dele.x, mouseY + dele.y);
                if ((lastIndex < 0) || (lastIndex > dataModel.rowCount()))
                    return ;
                if (index !== lastIndex){
                    dataModel.move(index, lastIndex, 1);
                }
                dele.toIndex = lastIndex;
            }
            onPressAndHold: dataModel.remove(index);
        }    
        DropArea{
            anchors.fill: parent
            onDropped: {
                var num = drag.source.index;
                var str = drag.source.str;
                dataModel.insert(index, {string: str, index: num})
            }
        }
    }
}
  1. ToolBox.qml
import QtQuick 2.12
import QtQuick.Controls 2.12
ListView{
    id: toolView;
    clip: false;
    spacing: 4;
    boundsBehavior:Flickable.StopAtBounds;
    property alias oModel: toolMod;
    
    model: ListModel {
        id: toolMod;
        ListElement{ iconSource: "qrc:/image/Test.png"; string: "111" }
        ListElement{ iconSource: "qrc:/image/Test.png"; string: "222" }
        ListElement{ iconSource: "qrc:/image/Test.png"; string: "333" }
    }
    //使用Column布局+Repeater动态创建内部组件的方式实现双层View
    delegate: Column {
        property alias iModel: innerModle;
        width: 200;
        anchors.horizontalCenter: parent.horizontalCenter;
        //height: 30+innerList.height;
        Rectangle{
            id: listDele; 
            width: 200;
            height: 30;
            color: "lightblue";
            property bool isopen: false;
            Image{
                id: toolIcon;
                width: 20;
                height: 20;
                source: iconSource;
                anchors.left: parent.left;
                anchors.top: parent.top;
                anchors.margins: 4;
                MouseArea{
                    anchors.fill: parent;
                    onClicked: {
                        listDele.isopen = !listDele.isopen;
                        toolView.update();
                    }
                }
            }
            
            Text {
                id: toolDescribe;
                text: string;
                anchors{
                    verticalCenter: parent.verticalCenter;
                    left: toolIcon.right;
                    leftMargin: 30;
                }
            }
        }
        Repeater{
            id: childList;
            model: ListModel{
                id: innerModle;
                ListElement{ iconSource: "qrc:/image/Test.png"; string: "111"; toolNumber: 0 }
                ListElement{ iconSource: "qrc:/image/Test.png"; string: "222"; toolNumber: 0 }
                ListElement{ iconSource: "qrc:/image/Test.png"; string: "333"; toolNumber: 0 }
            }
            
            delegate: Rectangle{
                color: "lightblue";
                width: parent.width;
                height: listDele.isopen? 30: 0;
                visible: listDele.isopen;
                //.active: true;
                property var tempItem;
                Image{
                    id: innerIcon;
                    width: 20;
                    height: 20;
                    source: iconSource;
                    anchors.left: parent.left;
                    anchors.top: parent.top;
                    anchors.topMargin: 4;
                    anchors.leftMargin: 30;
                }
                
                Text {
                    id: innerDescribe;
                    text: string;
                    anchors{
                        verticalCenter: parent.verticalCenter;
                        left: innerIcon.right;
                        leftMargin: 30;
                    }
                }
                MouseArea{
                    anchors.fill: parent;
                    //drag.target: parent;
                    property point clickPos: "0,0";
                    onPressed: {
                        tempItem = dragDele.createObject(parent, {});//防止原本元素移位,采用动态创建的方式进行拖拽添加
                        tempItem.changeProperty(string, iconSource);
//                        console.log(tempItem.str, tempItem.iconSource, 
//                                    tempItem.index);
                    }
                    onReleased: {
                        if(tempItem)
                            tempItem.destroy();
                    }
                    /*onPositionChanged: {
                        //鼠标偏移量
                        if(tempItem){
                            var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
                            //如果mainwindow继承自QWidget,用setPos
                            tempItem.x = tempItem.x+delta.x;     
                            tempItem.y = tempItem.y+delta.y;
                        }
                    }*/  ///这部分好像无效(想在拖动同时改变tempItem的位置,但不能显示
                }
            }
        }
    }
    Component{
        id: dragDele;
        Rectangle{
            id: dragRect;
            color: "lightblue";
            width: parent.width;
            height: 30;
            property string str;
            property string iconSource;
            property int index;
            Drag.active: true;
            Drag.dragType: Drag.Automatic;
            Drag.supportedActions: Qt.CopyAction;
            //Drag.mimeData: {"str": str, "iconSource": iconSource, "index": index}
            Image{
                id: innerIcon;
                width: 20;
                height: 20;
                source: iconSource;
                anchors.left: parent.left;
                anchors.top: parent.top;
                anchors.topMargin: 4;
                anchors.leftMargin: 30;
            }
            
            Text {
                id: innerDescribe;
                text: str;
                anchors{
                    verticalCenter: parent.verticalCenter;
                    left: innerIcon.right;
                    leftMargin: 30;
                }
            }
            MouseArea{
                anchors.fill: parent;
                drag.target: dragRect;
            }
            function changeProperty(s, i){
                str = s;
                iconSource = i;
                Drag.startDrag()//不使用这句的话
            }
        }
    }
    //Component.onCompleted: toolMod.remove(0);
}
发布了24 篇原创文章 · 获赞 14 · 访问量 6153

猜你喜欢

转载自blog.csdn.net/qq_35587463/article/details/93513622
今日推荐