qml拖拽

原文链接:https://blog.csdn.net/qq_36685813/article/details/102787140

在Qt5.10中qml实现的拖拽并不完善,以下Bug已在Qt5.12,Qt5.13中进行了修复。

在Qt Quick与 drag and drop 相关的几个QML Type:

DropArea 是不可见的,它定义了一个可以接收拖放的区域。它的 entered 信号在有物体被拖入区域时发射,exited 信号在物体被拖出区域时发射,当物体在区域内被拖着来回移动时会不断发射 positionChanged 信号,当用户释放了物体,dropped 信号被发射。在DropArea 中有以下几个Properties。containsDrag此属性标识DropArea当前是否包含任何拖动的项目,drag.x, drag.y 表示的是拖拽的坐标。

 

DragEvent ,它描述一个拖动事件的相关信息的, DropArea 的 entered 、 positionChanged 、 dropped 信号的参数都是 DragEvent 。它的Properties比较多,有需要就去看文档吧,这里挑几个比较常用的说说吧。

  • accepted :表示是否接受事件的布尔值,如果你处理了 entered 信号,需要把它设置为 true 。

  • x , y :拖动事件的位置,你可以根据它来显示点什么,我们的实例显示了一个如影随形的矩形。

  • action : 拖动来源正在执行的动作的标识,有 Qt.CopyAction 、 Qt.MoveAction 、 Qt.LinkAction 、 Qt.IgnoreAction四种。

  • proposedActions :建议的动作集合。

  • supportedActions :来源支持的动作集合

其它的属性还有 hasColor 、 hasUrls 、 hasText 、 hasHtml 等等与 MIME 相关的属性用来判断在拖动时是否携带了某种数据,对应的就有 colorData 、 urls 、 text 、 html 等属性表示实际的数据。

 

       DragEvent 还定义了一些方法:

  •     accept(Action) :调用它可以接受某一个动作,比如你接受 Qt.CopyAction

  •     accept() :接受拖动事件,表明你处理了这个事件了。

  •     acceptProposedAction() : 接受被拖动物体(来源)建议的动作

  •     getDataAsString(format) :获取某个格式对应的数据并转换为字符串,我们的实例里用这个来提取传输的数据

 

Drag 这个类一般是附着在可能被拖动的 Item 上,用来设置一些拖动相关的信息。

它提供很多附加属性:

  • active :指示当前是否处在拖动状态。我们可以把这个属性和一个 MouseArea 的 drag 属性绑定,这样当用户拖动鼠标时就会产生拖动事件。当然你也可以手动设置它为 true ,那样会以被拖动 Item 的当前位置产生一个拖动进入事件。如果你设置 active 为 false ,会产生一个拖动离开事件。
  • dragType :一个枚举值,表示拖动类型,可以是 Drag.None(不自动开始拖动)、Drag.Automatic(自动开始拖动)、Drag.Internal(自动开始前向兼容的拖动)。我们用到了这个,待会儿看代码就明白了。
  • mimeData : 存放MIME数据以及自定义数据,可以传递给 DropArea 。Qt Quick 会把 mimeData 定义的数据打包到 DragEvent 里,带着它四处旅行,谁感兴趣都可以看看。他需要与Qt.CopyAction一块使用,进行数据传输。在Image和Text中比较常用。
  • supportedActions :指定支持的动作。对应 DropArea 收到的 DragEvent 的 supportedActions 。
  • proposedActions : 指定推荐的动作。对应 DropArea 收到的 DragEvent 的 proposedActions 。
  • source : 指定拖动的来源对象
  • target :当 active 为 true (拖动处于活跃状态)时,这个属性保存被拖动物体进入的那个 DropArea ,如果被拖动物理和谁都没交集,那它就为 null 。如果拖动没被激活,那它保存最后一个接受 drop 事件的对象,要是没人招惹过被拖动物体,那 target 就为 null

Drag 还有一些附加信号,可以让我们对拖动的过程增进了解,比如 dragStarted 、 dragFinished 。

Drag 也提供了一些方法,如 cancel 、 drop 、 start 、 startDrag ,允许我们手动控制拖动

 

以下代码实现的是图片的拖动实例

本实例使用的是Qt.CopyAction,在Qt5.10中使用Qt.CopyAction类型进行拖动时,会出现一个Bug,需要用高版本的Qt能够解决。当你將Target,拖到指定的dargArea区域时,MouseArea区域的的onPressed不会再你松开鼠标时立即执行,需要你在次使用鼠标点击(当再次有相同的点击事件发生时)任意区域,上次的onPressed事件才会执行,这就会导致你想要再次拖图片时,如果不在任意地方点击一次,你对图片的拖动就不会成功,因为在你下次进行操作之前,你需要将上次操作的onPressed释放掉。

还有如果你是新手,进行Image加载时,将图片放到本地路径仍然加载不上(找不到),这时候就需要将要加载的图片,添加到执行的列表中,如下图:

 

直接上代码:

  
  
  1. import QtQuick 2.9
  2. import QtQuick.Window 2.2
  3. Window {
  4. id:win
  5. visible: true
  6. width: 640
  7. height: 480
  8. title: qsTr( "Hello World")
  9. Image{
  10. id: sourceImage
  11. height: 36
  12. width: 36
  13. anchors.left: parent.left
  14. anchors.leftMargin: 100
  15. anchors.verticalCenter: parent.verticalCenter
  16. source: "2.png"
  17. Drag.active: dragArea1.drag.active;
  18. Drag.supportedActions: Qt.CopyAction;
  19. Drag.dragType: Drag.Automatic;
  20. //Drag.dragType:Drag.Internal
  21. Drag.mimeData: { "pic": source}
  22. Drag.hotSpot.x: (sourceImage.width)* 0.5
  23. Drag.hotSpot.y: sourceImage.height
  24. MouseArea {
  25. id: dragArea1;
  26. anchors.fill: sourceImage;
  27. drag.target: sourceImage;
  28. onPressed: {
  29. console.log( 2222)
  30. }
  31. //在Qt5 .10中不会自动执行此步骤,需要再次点击才能释放上次的onReleased操作
  32. onReleased: {
  33. console.log( 33333)
  34. }
  35. }
  36. }
  37. Component.onCompleted: {
  38. sourceImage.grabToImage(function(result) {
  39. sourceImage.Drag.imageSource = result.url
  40. })
  41. }
  42. Rectangle{
  43. anchors.right: parent.right
  44. border.color: "blue"
  45. border.width: 1
  46. height: parent.height
  47. width: 300
  48. Image{
  49. id: targetImage
  50. height: sourceImage.height
  51. width: sourceImage.width
  52. clip: true
  53. }
  54. DropArea {
  55. id: dropContainer1
  56. anchors.fill: parent;
  57. onEntered: {
  58. console.log( 444444)
  59. }
  60. onDropped: {
  61. console.log( 55555)
  62. if (drop.supportedActions == Qt.CopyAction){
  63. targetImage.source = drop.getDataAsString( "pic")
  64. targetImage.x = drop.x - (sourceImage.width)* 0.5
  65. targetImage.y = drop.y - sourceImage.height
  66. drop.acceptProposedAction()
  67. }
  68. }
  69. onExited: {
  70. console.log( 66666)
  71. }
  72. }
  73. }
  74. }

代码中对拖拽的输出顺序用console.log()进行输出,可以很直观的看到。如果使用Qt5.10就能看到文中提到的Bug,官方已在更高的Qt版本中进行了修复。Qt5.13运行的效果如下:

 

为了更好的理解Qml中拖拽,下面在多上两端代码。

下面代码演示的是将窗口分为两个区域,在随机位置上,生成随机颜色并带编码的方块。可以对这些方块进行拖动,并使用动画增加了弹簧效果,在不同区域限制了拖动的效果。此代码在Qt5.10中也会遇到相同的Bug。

直接上代码:


  
  
  1. import QtQuick 2.9
  2. import QtQuick.Window 2.2
  3. Window {
  4. id:win
  5. visible: true
  6. width: 640
  7. height: 480
  8. title: qsTr( "Hello World")
  9. Repeater {
  10. model: 10
  11. Rectangle {
  12. id: rect
  13. width: 50
  14. height: 50
  15. z: mouseArea.drag.active || mouseArea.pressed ? 2 : 1
  16. color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
  17. x: Math.random() * (win.width / 2 - 100)
  18. y: Math.random() * (win.height - 100)
  19. property point beginDrag
  20. property bool caught: false
  21. border { width: 2; color: "white" }
  22. radius: 5
  23. Drag.active: mouseArea.drag.active
  24. Text {
  25. anchors.centerIn: parent
  26. text: index
  27. color: "white"
  28. }
  29. MouseArea {
  30. id: mouseArea
  31. anchors.fill: parent
  32. drag.target: parent
  33. onPressed: {
  34. rect.beginDrag = Qt.point(rect.x, rect.y);
  35. }
  36. onReleased: {
  37. if(!rect.caught) {
  38. backAnimX. from = rect.x;
  39. backAnimX.to = beginDrag.x;
  40. backAnimY. from = rect.y;
  41. backAnimY.to = beginDrag.y;
  42. backAnim.start()
  43. }
  44. }
  45. }
  46. ParallelAnimation {
  47. id: backAnim
  48. SpringAnimation { id: backAnimX; target: rect; property: "x"; duration: 500; spring: 2; damping: 0.2 }
  49. SpringAnimation { id: backAnimY; target: rect; property: "y"; duration: 500; spring: 2; damping: 0.2 }
  50. }
  51. }
  52. }
  53. Rectangle {
  54. anchors {
  55. top: parent.top
  56. right: parent.right
  57. bottom: parent.bottom
  58. }
  59. width: parent.width / 2
  60. color: "gold"
  61. DropArea {
  62. anchors.fill: parent
  63. onEntered: drag.source.caught = true;
  64. onExited: drag.source.caught = false;
  65. }
  66. }
  67. }
代码效果如下:

 

下面这段代码演示的也是方块的拖拽,与上面设计的方法有点不同,界面顶部是一些色块,只支持 Qt.CopyAction ,鼠标可以拖动,把它们拖到下面的浅蓝色区域内。一旦色块被拖放到浅蓝色区域,我会动态创建一个支持 Qt.MoveAction 的矩形,复制拖放的矩形的大小、颜色等参数。这样蓝色区域内新创建的这些 Rectangle 就可以被移动。单是移动没有限制区域,它可以全屏移动。

上代码:

  
  
  1. import QtQuick 2.9
  2. import QtQuick.Window 2.2
  3. import QtQuick.Window 2.2
  4. Window {
  5. id: root;
  6. visible: true;
  7. width: 480;
  8. height: 400;
  9. //drag source item should not use anchors to layout! or drag will failed
  10. Component {
  11. id: dragColor;
  12. Rectangle {
  13. id: dragItem;
  14. x: 0;
  15. y: 0;
  16. width: 60;
  17. height: 60;
  18. Drag.active: dragArea.drag.active;
  19. Drag.supportedActions: Qt.CopyAction;
  20. Drag.dragType: Drag.Automatic;
  21. Drag.mimeData: { "color": color, "width": width, "height": height}
  22. MouseArea {
  23. id: dragArea;
  24. anchors.fill: parent;
  25. drag.target: parent;
  26. onPressed: {
  27. console.log( 2222)
  28. parent.grabToImage(function(result) {
  29. dragColor.Drag.imageSource = result.url
  30. })
  31. }
  32. onReleased: {
  33. console.log( 333333)
  34. if(parent.Drag.supportedActions === Qt.CopyAction){
  35. dragItem.x = 0;
  36. dragItem.y = 0;
  37. }
  38. }
  39. }
  40. }
  41. }
  42. Row {
  43. id: dragSource;
  44. anchors.top: parent.top;
  45. anchors.left: parent.left;
  46. anchors.margins: 4;
  47. anchors.right: parent.right;
  48. height: 64;
  49. spacing: 4;
  50. z:- 1;
  51. Loader {
  52. width: 60;
  53. height: 60;
  54. z: 2;
  55. sourceComponent: dragColor;
  56. onLoaded: item.color = "red";
  57. }
  58. Loader {
  59. width: 60;
  60. height: 60;
  61. z: 2;
  62. sourceComponent: dragColor;
  63. onLoaded: item.color = "black";
  64. }
  65. Loader {
  66. width: 60;
  67. height: 60;
  68. z: 2;
  69. sourceComponent: dragColor;
  70. onLoaded: item.color = "blue";
  71. }
  72. Loader {
  73. width: 60;
  74. height: 60;
  75. z: 2;
  76. sourceComponent: dragColor;
  77. onLoaded: item.color = "green";
  78. }
  79. }
  80. DropArea {
  81. id: dropContainer;
  82. anchors.top: dragSource.bottom;
  83. anchors.left: parent.left;
  84. anchors.right: parent.right;
  85. anchors.bottom: parent.bottom;
  86. z: - 1;
  87. onEntered: {
  88. drag.accepted = true;
  89. followArea.color = drag.getDataAsString( "color");
  90. console.log( "onEntered, formats - ", drag.formats, " action - ", drag.action);
  91. }
  92. onPositionChanged: {
  93. console.log( 11111111)
  94. drag.accepted = true;
  95. console.log( 1,followArea.x,followArea.y)
  96. console.log( 2,drag.x,drag.y)
  97. followArea.x = drag.x ;
  98. followArea.y = drag.y ;
  99. }
  100. onDropped: {
  101. console.log( 44444)
  102. if(drop.supportedActions == Qt.CopyAction){
  103. var obj = dragColor.createObject(destArea,{
  104. "x": drop.x,
  105. "y": drop.y,
  106. "width": parseInt(drop.getDataAsString( "width")),
  107. "height": parseInt(drop.getDataAsString( "height")),
  108. "color": drop.getDataAsString( "color"),
  109. "Drag.supportedActions": Qt.MoveAction,
  110. "Drag.dragType": Drag.Internal
  111. });
  112. } else if(drop.supportedActions == Qt.MoveAction){
  113. console.log( "move action, drop.source - ", drop.source, " drop.source.source - ", drop.source.source);
  114. }
  115. drop.acceptProposedAction();
  116. drop.accepted = true;
  117. }
  118. Rectangle {
  119. id: followArea;
  120. z: 2;
  121. width: 68;
  122. height: 68;
  123. border.width: 2;
  124. border.color: "yellow";
  125. visible: parent.containsDrag;
  126. }
  127. Rectangle {
  128. id: destArea;
  129. anchors.fill: parent;
  130. color: "lightsteelblue";
  131. border.width: 2;
  132. border.color: parent.containsDrag ? "blue" : "gray";
  133. }
  134. }
  135. }
代码效果如下:

代码数量较少,比较简单,自己可以多看看。

 

在Qt5.10中qml实现的拖拽并不完善,以下Bug已在Qt5.12,Qt5.13中进行了修复。

在Qt Quick与 drag and drop 相关的几个QML Type:

DropArea 是不可见的,它定义了一个可以接收拖放的区域。它的 entered 信号在有物体被拖入区域时发射,exited 信号在物体被拖出区域时发射,当物体在区域内被拖着来回移动时会不断发射 positionChanged 信号,当用户释放了物体,dropped 信号被发射。在DropArea 中有以下几个Properties。containsDrag此属性标识DropArea当前是否包含任何拖动的项目,drag.x, drag.y 表示的是拖拽的坐标。

 

DragEvent ,它描述一个拖动事件的相关信息的, DropArea 的 entered 、 positionChanged 、 dropped 信号的参数都是 DragEvent 。它的Properties比较多,有需要就去看文档吧,这里挑几个比较常用的说说吧。

  • accepted :表示是否接受事件的布尔值,如果你处理了 entered 信号,需要把它设置为 true 。

  • x , y :拖动事件的位置,你可以根据它来显示点什么,我们的实例显示了一个如影随形的矩形。

  • action : 拖动来源正在执行的动作的标识,有 Qt.CopyAction 、 Qt.MoveAction 、 Qt.LinkAction 、 Qt.IgnoreAction四种。

  • proposedActions :建议的动作集合。

  • supportedActions :来源支持的动作集合

其它的属性还有 hasColor 、 hasUrls 、 hasText 、 hasHtml 等等与 MIME 相关的属性用来判断在拖动时是否携带了某种数据,对应的就有 colorData 、 urls 、 text 、 html 等属性表示实际的数据。

 

       DragEvent 还定义了一些方法:

  •     accept(Action) :调用它可以接受某一个动作,比如你接受 Qt.CopyAction

  •     accept() :接受拖动事件,表明你处理了这个事件了。

  •     acceptProposedAction() : 接受被拖动物体(来源)建议的动作

  •     getDataAsString(format) :获取某个格式对应的数据并转换为字符串,我们的实例里用这个来提取传输的数据

 

Drag 这个类一般是附着在可能被拖动的 Item 上,用来设置一些拖动相关的信息。

它提供很多附加属性:

  • active :指示当前是否处在拖动状态。我们可以把这个属性和一个 MouseArea 的 drag 属性绑定,这样当用户拖动鼠标时就会产生拖动事件。当然你也可以手动设置它为 true ,那样会以被拖动 Item 的当前位置产生一个拖动进入事件。如果你设置 active 为 false ,会产生一个拖动离开事件。
  • dragType :一个枚举值,表示拖动类型,可以是 Drag.None(不自动开始拖动)、Drag.Automatic(自动开始拖动)、Drag.Internal(自动开始前向兼容的拖动)。我们用到了这个,待会儿看代码就明白了。
  • mimeData : 存放MIME数据以及自定义数据,可以传递给 DropArea 。Qt Quick 会把 mimeData 定义的数据打包到 DragEvent 里,带着它四处旅行,谁感兴趣都可以看看。他需要与Qt.CopyAction一块使用,进行数据传输。在Image和Text中比较常用。
  • supportedActions :指定支持的动作。对应 DropArea 收到的 DragEvent 的 supportedActions 。
  • proposedActions : 指定推荐的动作。对应 DropArea 收到的 DragEvent 的 proposedActions 。
  • source : 指定拖动的来源对象
  • target :当 active 为 true (拖动处于活跃状态)时,这个属性保存被拖动物体进入的那个 DropArea ,如果被拖动物理和谁都没交集,那它就为 null 。如果拖动没被激活,那它保存最后一个接受 drop 事件的对象,要是没人招惹过被拖动物体,那 target 就为 null

Drag 还有一些附加信号,可以让我们对拖动的过程增进了解,比如 dragStarted 、 dragFinished 。

Drag 也提供了一些方法,如 cancel 、 drop 、 start 、 startDrag ,允许我们手动控制拖动

 

以下代码实现的是图片的拖动实例

本实例使用的是Qt.CopyAction,在Qt5.10中使用Qt.CopyAction类型进行拖动时,会出现一个Bug,需要用高版本的Qt能够解决。当你將Target,拖到指定的dargArea区域时,MouseArea区域的的onPressed不会再你松开鼠标时立即执行,需要你在次使用鼠标点击(当再次有相同的点击事件发生时)任意区域,上次的onPressed事件才会执行,这就会导致你想要再次拖图片时,如果不在任意地方点击一次,你对图片的拖动就不会成功,因为在你下次进行操作之前,你需要将上次操作的onPressed释放掉。

还有如果你是新手,进行Image加载时,将图片放到本地路径仍然加载不上(找不到),这时候就需要将要加载的图片,添加到执行的列表中,如下图:

 

直接上代码:

  
  
  1. import QtQuick 2.9
  2. import QtQuick.Window 2.2
  3. Window {
  4. id:win
  5. visible: true
  6. width: 640
  7. height: 480
  8. title: qsTr( "Hello World")
  9. Image{
  10. id: sourceImage
  11. height: 36
  12. width: 36
  13. anchors.left: parent.left
  14. anchors.leftMargin: 100
  15. anchors.verticalCenter: parent.verticalCenter
  16. source: "2.png"
  17. Drag.active: dragArea1.drag.active;
  18. Drag.supportedActions: Qt.CopyAction;
  19. Drag.dragType: Drag.Automatic;
  20. //Drag.dragType:Drag.Internal
  21. Drag.mimeData: { "pic": source}
  22. Drag.hotSpot.x: (sourceImage.width)* 0.5
  23. Drag.hotSpot.y: sourceImage.height
  24. MouseArea {
  25. id: dragArea1;
  26. anchors.fill: sourceImage;
  27. drag.target: sourceImage;
  28. onPressed: {
  29. console.log( 2222)
  30. }
  31. //在Qt5 .10中不会自动执行此步骤,需要再次点击才能释放上次的onReleased操作
  32. onReleased: {
  33. console.log( 33333)
  34. }
  35. }
  36. }
  37. Component.onCompleted: {
  38. sourceImage.grabToImage(function(result) {
  39. sourceImage.Drag.imageSource = result.url
  40. })
  41. }
  42. Rectangle{
  43. anchors.right: parent.right
  44. border.color: "blue"
  45. border.width: 1
  46. height: parent.height
  47. width: 300
  48. Image{
  49. id: targetImage
  50. height: sourceImage.height
  51. width: sourceImage.width
  52. clip: true
  53. }
  54. DropArea {
  55. id: dropContainer1
  56. anchors.fill: parent;
  57. onEntered: {
  58. console.log( 444444)
  59. }
  60. onDropped: {
  61. console.log( 55555)
  62. if (drop.supportedActions == Qt.CopyAction){
  63. targetImage.source = drop.getDataAsString( "pic")
  64. targetImage.x = drop.x - (sourceImage.width)* 0.5
  65. targetImage.y = drop.y - sourceImage.height
  66. drop.acceptProposedAction()
  67. }
  68. }
  69. onExited: {
  70. console.log( 66666)
  71. }
  72. }
  73. }
  74. }

代码中对拖拽的输出顺序用console.log()进行输出,可以很直观的看到。如果使用Qt5.10就能看到文中提到的Bug,官方已在更高的Qt版本中进行了修复。Qt5.13运行的效果如下:

 

为了更好的理解Qml中拖拽,下面在多上两端代码。

下面代码演示的是将窗口分为两个区域,在随机位置上,生成随机颜色并带编码的方块。可以对这些方块进行拖动,并使用动画增加了弹簧效果,在不同区域限制了拖动的效果。此代码在Qt5.10中也会遇到相同的Bug。

直接上代码:


  
  
  1. import QtQuick 2.9
  2. import QtQuick.Window 2.2
  3. Window {
  4. id:win
  5. visible: true
  6. width: 640
  7. height: 480
  8. title: qsTr( "Hello World")
  9. Repeater {
  10. model: 10
  11. Rectangle {
  12. id: rect
  13. width: 50
  14. height: 50
  15. z: mouseArea.drag.active || mouseArea.pressed ? 2 : 1
  16. color: Qt.rgba(Math.random(), Math.random(), Math.random(), 1)
  17. x: Math.random() * (win.width / 2 - 100)
  18. y: Math.random() * (win.height - 100)
  19. property point beginDrag
  20. property bool caught: false
  21. border { width: 2; color: "white" }
  22. radius: 5
  23. Drag.active: mouseArea.drag.active
  24. Text {
  25. anchors.centerIn: parent
  26. text: index
  27. color: "white"
  28. }
  29. MouseArea {
  30. id: mouseArea
  31. anchors.fill: parent
  32. drag.target: parent
  33. onPressed: {
  34. rect.beginDrag = Qt.point(rect.x, rect.y);
  35. }
  36. onReleased: {
  37. if(!rect.caught) {
  38. backAnimX. from = rect.x;
  39. backAnimX.to = beginDrag.x;
  40. backAnimY. from = rect.y;
  41. backAnimY.to = beginDrag.y;
  42. backAnim.start()
  43. }
  44. }
  45. }
  46. ParallelAnimation {
  47. id: backAnim
  48. SpringAnimation { id: backAnimX; target: rect; property: "x"; duration: 500; spring: 2; damping: 0.2 }
  49. SpringAnimation { id: backAnimY; target: rect; property: "y"; duration: 500; spring: 2; damping: 0.2 }
  50. }
  51. }
  52. }
  53. Rectangle {
  54. anchors {
  55. top: parent.top
  56. right: parent.right
  57. bottom: parent.bottom
  58. }
  59. width: parent.width / 2
  60. color: "gold"
  61. DropArea {
  62. anchors.fill: parent
  63. onEntered: drag.source.caught = true;
  64. onExited: drag.source.caught = false;
  65. }
  66. }
  67. }
代码效果如下:

 

下面这段代码演示的也是方块的拖拽,与上面设计的方法有点不同,界面顶部是一些色块,只支持 Qt.CopyAction ,鼠标可以拖动,把它们拖到下面的浅蓝色区域内。一旦色块被拖放到浅蓝色区域,我会动态创建一个支持 Qt.MoveAction 的矩形,复制拖放的矩形的大小、颜色等参数。这样蓝色区域内新创建的这些 Rectangle 就可以被移动。单是移动没有限制区域,它可以全屏移动。

上代码:

  
  
  1. import QtQuick 2.9
  2. import QtQuick.Window 2.2
  3. import QtQuick.Window 2.2
  4. Window {
  5. id: root;
  6. visible: true;
  7. width: 480;
  8. height: 400;
  9. //drag source item should not use anchors to layout! or drag will failed
  10. Component {
  11. id: dragColor;
  12. Rectangle {
  13. id: dragItem;
  14. x: 0;
  15. y: 0;
  16. width: 60;
  17. height: 60;
  18. Drag.active: dragArea.drag.active;
  19. Drag.supportedActions: Qt.CopyAction;
  20. Drag.dragType: Drag.Automatic;
  21. Drag.mimeData: { "color": color, "width": width, "height": height}
  22. MouseArea {
  23. id: dragArea;
  24. anchors.fill: parent;
  25. drag.target: parent;
  26. onPressed: {
  27. console.log( 2222)
  28. parent.grabToImage(function(result) {
  29. dragColor.Drag.imageSource = result.url
  30. })
  31. }
  32. onReleased: {
  33. console.log( 333333)
  34. if(parent.Drag.supportedActions === Qt.CopyAction){
  35. dragItem.x = 0;
  36. dragItem.y = 0;
  37. }
  38. }
  39. }
  40. }
  41. }
  42. Row {
  43. id: dragSource;
  44. anchors.top: parent.top;
  45. anchors.left: parent.left;
  46. anchors.margins: 4;
  47. anchors.right: parent.right;
  48. height: 64;
  49. spacing: 4;
  50. z:- 1;
  51. Loader {
  52. width: 60;
  53. height: 60;
  54. z: 2;
  55. sourceComponent: dragColor;
  56. onLoaded: item.color = "red";
  57. }
  58. Loader {
  59. width: 60;
  60. height: 60;
  61. z: 2;
  62. sourceComponent: dragColor;
  63. onLoaded: item.color = "black";
  64. }
  65. Loader {
  66. width: 60;
  67. height: 60;
  68. z: 2;
  69. sourceComponent: dragColor;
  70. onLoaded: item.color = "blue";
  71. }
  72. Loader {
  73. width: 60;
  74. height: 60;
  75. z: 2;
  76. sourceComponent: dragColor;
  77. onLoaded: item.color = "green";
  78. }
  79. }
  80. DropArea {
  81. id: dropContainer;
  82. anchors.top: dragSource.bottom;
  83. anchors.left: parent.left;
  84. anchors.right: parent.right;
  85. anchors.bottom: parent.bottom;
  86. z: - 1;
  87. onEntered: {
  88. drag.accepted = true;
  89. followArea.color = drag.getDataAsString( "color");
  90. console.log( "onEntered, formats - ", drag.formats, " action - ", drag.action);
  91. }
  92. onPositionChanged: {
  93. console.log( 11111111)
  94. drag.accepted = true;
  95. console.log( 1,followArea.x,followArea.y)
  96. console.log( 2,drag.x,drag.y)
  97. followArea.x = drag.x ;
  98. followArea.y = drag.y ;
  99. }
  100. onDropped: {
  101. console.log( 44444)
  102. if(drop.supportedActions == Qt.CopyAction){
  103. var obj = dragColor.createObject(destArea,{
  104. "x": drop.x,
  105. "y": drop.y,
  106. "width": parseInt(drop.getDataAsString( "width")),
  107. "height": parseInt(drop.getDataAsString( "height")),
  108. "color": drop.getDataAsString( "color"),
  109. "Drag.supportedActions": Qt.MoveAction,
  110. "Drag.dragType": Drag.Internal
  111. });
  112. } else if(drop.supportedActions == Qt.MoveAction){
  113. console.log( "move action, drop.source - ", drop.source, " drop.source.source - ", drop.source.source);
  114. }
  115. drop.acceptProposedAction();
  116. drop.accepted = true;
  117. }
  118. Rectangle {
  119. id: followArea;
  120. z: 2;
  121. width: 68;
  122. height: 68;
  123. border.width: 2;
  124. border.color: "yellow";
  125. visible: parent.containsDrag;
  126. }
  127. Rectangle {
  128. id: destArea;
  129. anchors.fill: parent;
  130. color: "lightsteelblue";
  131. border.width: 2;
  132. border.color: parent.containsDrag ? "blue" : "gray";
  133. }
  134. }
  135. }
代码效果如下:

代码数量较少,比较简单,自己可以多看看。

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值