qml demo分析(externaldraganddrop-拖拽)

一、效果展示

  客户端程序拖拽是一个很常见的需求,对于QWidget程序来说,需要重写如图1这么几个方法,通过重写这几个方法的逻辑,我们就可以控制鼠标拖拽的逻辑,糟糕的是QDrag执行exec后是一个阻塞主事件循环的操作,这个时候除了拖拽界面外,其他界面不能响应鼠标事件。作者之前就有过这么一个需要主界面响应的需求,当时我是重写了如图2所示的接口,来模拟程序拖拽。

图1 QWidget拖拽接口

图2 QWidget鼠标事件

   如图3所示是示例拖拽展示,界面上有3个大的EditText,相互之间可以进行拖拽,将文本移动到新的EditText。

图3 示例拖拽

二、源码分析

  这个示例代码只有2个qml文件,一个是自定义的组件DragAndDropTextItem,另一个是主界面布局。

1、自定义组件DragAndDropTextItem

  自定义组件DragAndDropTextItem根节点是Rectangle,支持鼠标事件,MouseArea捕获整个根节点的是标事件,并设置拖拽对象为draggable组件。DraopArea区域有许多槽函数,这些槽函数会自动被调用,比如onEntered,当鼠标进行的时候被调用,onExited当鼠标离开时被调用,具体代码如下

 1 import QtQuick 2.2
 2 
 3 Rectangle {
 4     id: item
 5     property string display//导出属性
 6     color: "#EEE"//自定义矩形背景色
 7     Text {
 8         anchors.fill: parent
 9         text: item.display//文本显示绑定导出属性(文本字符串)
10         wrapMode: Text.WordWrap//文本按字折行
11     }
12     DropArea {//拖拽区域
13         anchors.fill: parent
14         keys: ["text/plain"]//该字段对应draggable中mimeData
15         onEntered: {
16             item.color = "#FCC"
17         }
18         onExited: {
19             item.color = "#EEE"//鼠标拖拽退出时恢复常规背景色
20         }
21         onDropped: {//鼠标拖拽完成  释放时触发
22             item.color = "#EEE"
23             if (drop.hasText) {//拖拽含有文本字符串
24                 if (drop.proposedAction == Qt.MoveAction || drop.proposedAction == Qt.CopyAction) {
25                     item.display = drop.text//重置当前显示文本
26                     drop.acceptProposedAction()//接受目标动作,停止事件传递
27                 }
28             }
29         }
30     }
31     //鼠标事件区域,覆盖整个矩形
32     MouseArea {
33         id: mouseArea
34         anchors.fill: parent
35         drag.target: draggable//拖拽目标指定
36     }
37     Item {
38         id: draggable//
39         anchors.fill: parent
40         Drag.active: mouseArea.drag.active
41         Drag.hotSpot.x: 10//热点位置
42         Drag.hotSpot.y: 10
43         Drag.mimeData: { "text/plain": item.display }//设置拖拽时内部数据
44         Drag.dragType: Drag.Automatic//拖拽类型
45         Drag.onDragStarted: {//拖拽开始
46         }
47         Drag.onDragFinished: {//拖拽结束  拖拽操作状态为接受  
48             if (dropAction == Qt.MoveAction) {//如果是移动操作,将显示置空
49                 item.display = ""//清空被拖拽文本框
50             }
51         }
52     } // Item
53 }

2、主界面布局

  主界面使用了列布局器ColumnLayout,第一行是一个Text文本,显示该应用程序的基本描述信息,接下来3行是3个自定义控件DragAndDropTextItem,代码如下

 1 import QtQuick 2.2
 2 import QtQuick.Layouts 1.0
 3 
 4 Item {
 5     id: root//作用域内 唯一标示
 6      320
 7     height: 480
 8 
 9     ColumnLayout {//列布局器,类似于GridLayout  但是只有一列
10 
11         anchors.fill: parent
12         anchors.margins: 8
13 
14         Text {//第一行显示一串文本
15             Layout.fillWidth: true
16             text: "Drag text into, out of, and between the boxes below."
17             wrapMode: Text.WordWrap
18         }
19 
20         //支持拖拽自定义控件
21         DragAndDropTextItem {
22             Layout.fillWidth: true
23             height: 142
24             display: "Sample Text"
25         }
26 
27         //支持拖拽自定义控件
28         DragAndDropTextItem {
29             Layout.fillWidth: true
30             height: 142
31             display: "Option/ctrl drag to copy instead of move text."
32         }
33 
34         //支持拖拽自定义控件
35         DragAndDropTextItem {
36             Layout.fillWidth: true
37             height: 142
38             display: "Drag out into other applications."
39         }
40     }
41 }
原文地址:https://www.cnblogs.com/swarmbees/p/6604990.html