Эдуард Неткачёв
March 25, 2022, 12:29 a.m.

Выделение нескольких объектов

QML, выделение нескольких элементов мышкой

Приветствую всех.
Не могу разобраться как сделать выделение нескольких элементов с помощью удержания клавиши мыши. Уже разные способы пробовал, но каждый раз какой-то затык.

Вот кусок основной программы main.qml:

  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3. import QtQuick.Controls 2.5
  4.  
  5. ApplicationWindow {
  6. visible: true
  7. title: qsTr("Selection and Scaling")
  8. width: Screen.desktopAvailableWidth*50/100
  9. height: Screen.desktopAvailableHeight*80/100
  10. color: "whitesmoke"
  11.  
  12. property double my_scale: 1.0
  13.  
  14. Flickable {
  15. id: _scrollSetup
  16. anchors.fill: parent
  17. boundsMovement: Flickable.StopAtBounds // если контент больше видимой области, то при перемещении контента он останавливается на границе контента с видимой областью
  18. contentWidth: _сolumn.width*my_scale >parent.width ? (_сolumn.width*my_scale):parent.width
  19. contentHeight: _сolumn.height*my_scale >parent.height ? (_сolumn.height*my_scale):parent.height
  20. MouseArea {
  21. id: _mouseFlickable
  22. anchors.fill: parent
  23. property point clickPos: "0,0"
  24. onWheel: if (wheel.angleDelta.y>0) { my_scale*=1.05; } else { my_scale*=0.95; } // реакция на скролл
  25. onClicked: console.log("_mouseFlickable.onClicked");
  26. onPressed: { console.log("_mouseFlickable.onPressed");
  27. clickPos = Qt.point(mouse.x,mouse.y)
  28. _rect_select.x=clickPos.x; _rect_select.y=clickPos.y;
  29. _rect_select.width=0; _rect_select.height=0;
  30. _rect_select.visible=true;
  31. }
  32. onReleased: { console.log("_mouseFlickable.onReleased");
  33. _rect_select.visible=false;
  34. }
  35. onEntered: console.log("_mouseFlickable.onEntered");
  36. onExited: console.log("_mouseFlickable.onExited");
  37. onPositionChanged: {
  38. _rect_select.x=Math.min(mouse.x,clickPos.x)
  39. _rect_select.y=Math.min(mouse.y,clickPos.y)
  40. _rect_select.width=Math.abs(clickPos.x-mouse.x)
  41. _rect_select.height=Math.abs(clickPos.y-mouse.y)
  42. }
  43. Column {
  44. id: _сolumn
  45. anchors.verticalCenter: parent.verticalCenter
  46. anchors.horizontalCenter: parent.horizontalCenter
  47. scale: my_scale
  48.  
  49. Row {
  50. id: _rowUpper
  51. MyElement {
  52. id: element_1
  53. number: 1
  54. height: 160
  55. width: 160
  56. }
  57. MyElement {
  58. id: element_2
  59. number: 2
  60. height: 160
  61. width: 160
  62. }
  63. MyElement {
  64. id: element_3
  65. number: 3
  66. height: 160
  67. width: 160
  68. }
  69. MyElement {
  70. id: element_4
  71. number: 4
  72. height: 160
  73. width: 160
  74. }
  75. }
  76. Rectangle {
  77. anchors.horizontalCenter: parent.horizontalCenter
  78. height: 4
  79. color: "lightsteelblue"
  80. width: parent.width
  81. }
  82. Row {
  83. id: _rowLower
  84. MyElement {
  85. id: element_5
  86. number: 5
  87. height: 160
  88. width: 160
  89. }
  90. MyElement {
  91. id: element_6
  92. number: 6
  93. height: 160
  94. width: 160
  95. }
  96. MyElement {
  97. id: element_7
  98. number: 7
  99. height: 160
  100. width: 160
  101. }
  102. MyElement {
  103. id: element_8
  104. number: 8
  105. height: 160
  106. width: 160
  107. }
  108. }
  109. }
  110. }
  111. }
  112.  
  113. Rectangle {
  114. id: _rect_select
  115. visible: false
  116. color: "blue"
  117. opacity : 0.3
  118. }
  119. }

Вот код элемента MyElement.qml:

  1. import QtQuick 2.0
  2.  
  3. Item {
  4. property int number: 0
  5. property bool select: false
  6.  
  7. MouseArea {
  8. id: _mouseArea
  9. anchors.fill: parent
  10. hoverEnabled: true // это для работы функции containsMouse (наведение курсора мыши на область)
  11. propagateComposedEvents: true
  12. onClicked: { console.log("_mouse_" + number + ".onClicked"); mouse.accepted = false; }
  13. onPressed: { console.log("_mouse_" + number + ".onPressed"); mouse.accepted = false; }
  14. onReleased:{ console.log("_mouse_" + number + ".onReleased"); mouse.accepted = false; }
  15. onEntered: { console.log("_mouse_" + number + ".onEntered"); }
  16. onExited: { console.log("_mouse_" + number + ".onExited"); }
  17.  
  18. Rectangle {
  19. id: _rect
  20. anchors.fill: parent
  21. color: "green"
  22. scale: select ? 1.0 : _mouseArea.containsMouse ? 0.95 : 0.90
  23. }
  24. }
  25. }

Может есть мысли как это сделать.

2

Do you like it? Share on social networks!

1
P
  • March 28, 2022, 1:29 a.m.
  • The answer was marked as a solution.

Как вариант, считать пересечение объектов с прямоугольником выделения,
примерный код набрасал:

  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3. import QtQuick.Controls 2.5
  4.  
  5. ApplicationWindow {
  6. visible: true
  7. title: qsTr("Selection and Scaling")
  8. width: Screen.desktopAvailableWidth*50/100
  9. height: Screen.desktopAvailableHeight*80/100
  10. color: "whitesmoke"
  11.  
  12. property double my_scale: 1.0
  13.  
  14. Flickable {
  15. id: _scrollSetup
  16. anchors.fill: parent
  17. boundsMovement: Flickable.StopAtBounds // если контент больше видимой области, то при перемещении контента он останавливается на границе контента с видимой областью
  18. contentWidth: _сolumn.width*my_scale >parent.width ? (_сolumn.width*my_scale):parent.width
  19. contentHeight: _сolumn.height*my_scale >parent.height ? (_сolumn.height*my_scale):parent.height
  20. MouseArea {
  21. id: _mouseFlickable
  22. anchors.fill: parent
  23. property point clickPos: "0,0"
  24. onWheel: if (wheel.angleDelta.y>0) { my_scale*=1.05; } else { my_scale*=0.95; } // реакция на скролл
  25. onClicked: console.log("_mouseFlickable.onClicked");
  26. onPressed: { console.log("_mouseFlickable.onPressed");
  27. clickPos = Qt.point(mouse.x,mouse.y)
  28. _rect_select.x=clickPos.x; _rect_select.y=clickPos.y;
  29. _rect_select.width=0; _rect_select.height=0;
  30. _rect_select.visible=true;
  31. }
  32. onReleased: { console.log("_mouseFlickable.onReleased");
  33. _rect_select.visible=false;
  34. }
  35. onEntered: console.log("_mouseFlickable.onEntered");
  36. onExited: console.log("_mouseFlickable.onExited");
  37. onPositionChanged: {
  38. _rect_select.x=Math.min(mouse.x,clickPos.x)
  39. _rect_select.y=Math.min(mouse.y,clickPos.y)
  40. _rect_select.width=Math.abs(clickPos.x-mouse.x)
  41. _rect_select.height=Math.abs(clickPos.y-mouse.y)
  42. }
  43. Column {
  44. id: _сolumn
  45. anchors.verticalCenter: parent.verticalCenter
  46. anchors.horizontalCenter: parent.horizontalCenter
  47. scale: my_scale
  48.  
  49. Row {
  50. id: _rowUpper
  51. MyElement {
  52. id: element_1
  53. selectionRectangle: _rect_select
  54. number: 1
  55. height: 160
  56. width: 160
  57. }
  58. MyElement {
  59. id: element_2
  60. selectionRectangle: _rect_select
  61. number: 2
  62. height: 160
  63. width: 160
  64. }
  65. MyElement {
  66. id: element_3
  67. selectionRectangle: _rect_select
  68. number: 3
  69. height: 160
  70. width: 160
  71. }
  72. MyElement {
  73. id: element_4
  74. selectionRectangle: _rect_select
  75. number: 4
  76. height: 160
  77. width: 160
  78. }
  79. }
  80. Rectangle {
  81. anchors.horizontalCenter: parent.horizontalCenter
  82. height: 4
  83. color: "lightsteelblue"
  84. width: parent.width
  85. }
  86. Row {
  87. id: _rowLower
  88. MyElement {
  89. id: element_5
  90. selectionRectangle: _rect_select
  91. number: 5
  92. height: 160
  93. width: 160
  94. }
  95. MyElement {
  96. id: element_6
  97. selectionRectangle: _rect_select
  98. number: 6
  99. height: 160
  100. width: 160
  101. }
  102. MyElement {
  103. id: element_7
  104. selectionRectangle: _rect_select
  105. number: 7
  106. height: 160
  107. width: 160
  108. }
  109. MyElement {
  110. id: element_8
  111. selectionRectangle: _rect_select
  112. number: 8
  113. height: 160
  114. width: 160
  115. }
  116. }
  117. }
  118. }
  119. }
  120.  
  121. Rectangle {
  122. id: _rect_select
  123. visible: false
  124. color: "blue"
  125. opacity : 0.3
  126. }
  127. }
  128.  
  1. import QtQuick 2.0
  2.  
  3. Item {
  4. id: _item
  5. property int number: 0
  6. property bool select: false
  7. property QtObject selectionRectangle
  8.  
  9. MouseArea {
  10. id: _mouseArea
  11. anchors.fill: parent
  12. hoverEnabled: true // это для работы функции containsMouse (наведение курсора мыши на область)
  13. propagateComposedEvents: true
  14. onClicked: { console.log("_mouse_" + number + ".onClicked"); mouse.accepted = false; }
  15. onPressed: { console.log("_mouse_" + number + ".onPressed"); mouse.accepted = false; }
  16. onReleased:{ console.log("_mouse_" + number + ".onReleased"); mouse.accepted = false; }
  17. onEntered: { console.log("_mouse_" + number + ".onEntered"); }
  18. onExited: { console.log("_mouse_" + number + ".onExited"); }
  19.  
  20. Rectangle {
  21. id: _rect
  22. anchors.fill: parent
  23. color: "green"
  24. scale: select ? 1.0 : _mouseArea.containsMouse ? 0.95 : 0.90
  25.  
  26. }
  27. }
  28.  
  29. Connections {
  30. target: selectionRectangle
  31. function onHeightChanged() {
  32. intersect(_rect, selectionRectangle)
  33. }
  34. }
  35.  
  36. Connections {
  37. target: selectionRectangle
  38. function onWidthChanged() {
  39. intersect(_rect, selectionRectangle)
  40. }
  41. }
  42.  
  43.  
  44. function intersect(rect1, rect2) {
  45. var r1 = rect1.mapToItem(null, 0, 0, rect1.width, rect1.height)
  46. var r2 = rect2.mapToItem(null, 0, 0, rect2.width, rect2.height)
  47.  
  48. var xOverlap = Math.min(r1.x + r1.width, r2.x + r2.width) - Math.max(r1.x, r2.x);
  49. var yOverlap = Math.min(r1.y + r1.height, r2.y + r2.height) - Math.max(r1.y, r2.y);
  50.  
  51. if (xOverlap >= 0 && yOverlap >= 0) {
  52. _item.select = true
  53. } else {
  54. _item.select = false
  55. }
  56. }
  57.  
  58. }
  59.  

    Comments

    Only authorized users can post comments.
    Please, Log in or Sign up
    • Last comments
    • AK
      April 1, 2025, 11:41 a.m.
      Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
    • Evgenii Legotckoi
      March 9, 2025, 9:02 p.m.
      К сожалению, я этого подсказать не могу, поскольку у меня нет необходимости в обходе блокировок и т.д. Поэтому я и не задавался решением этой проблемы. Ну выглядит так, что вам действитель…
    • VP
      March 9, 2025, 4:14 p.m.
      Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
    • ИМ
      Nov. 22, 2024, 9:51 p.m.
      Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
    • Evgenii Legotckoi
      Oct. 31, 2024, 11:37 p.m.
      Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup