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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM