М
July 27, 2020, 5:35 p.m.

Flow QML Type: связь с моделью, динамическое добавление и удаление элементов

views, QML, View, flow, view, model, qml, вёрстка qml, Model

Надо: подтягивать из с++ список слов, делать из них кнопки. Ширина кнопок соответствует ширине текста. При заполнении одной строки (ряда) - переход на следующую.

С передачей данных из с++, сигналами и слотами, вроде пока понятно. На данный момент затруднения с вёрсткой. ListView и GridView не подходят.

Подходит Flow QML Type, но с ним нельзя работать как с моделью-представлением. Или можно?

https://doc.qt.io/qt-5/qml-qtquick-flow.html

Как динамически добавлять-убирать элементы Flow?

И как применить свойства для каждого элемента Flow, как в данном случае это сделано для первого id: first_button

  1. import QtQuick 2.12
  2. import QtQuick.Window 2.12
  3. import QtQuick.Controls 2.12
  4.  
  5. Window {
  6. visible: true
  7. width: 640
  8. height: 480
  9. title: qsTr("Hello World")
  10.  
  11. Flow {
  12. id: flow_id
  13. anchors.top: parent.top
  14. anchors.horizontalCenter: parent.horizontalCenter
  15. anchors.margins: 4
  16. spacing: 10
  17. width: parent.width/1.5
  18.  
  19. Button {
  20. id: first_button
  21. Text {
  22. id: first_button_text
  23. text: "Text"
  24. font.pointSize: 15
  25. anchors.horizontalCenter: parent.horizontalCenter
  26. anchors.verticalCenter: parent.verticalCenter
  27. verticalAlignment: Text.AlignVCenter
  28. horizontalAlignment: Text.AlignHCenter
  29. }
  30. width: first_button_text.width + 12
  31. }
  32. Button { text: "items"; font.pointSize: 15 }
  33. Button { text: "flowing"; font.pointSize: 15 }
  34. Button { text: "inside"; font.pointSize: 15 }
  35. Button { text: "a"; font.pointSize: 15 }
  36. Button { text: "Flow"; font.pointSize: 15 }
  37. Button { text: "item"; font.pointSize: 15 }
  38. }
  39.  
  40.  
  41. }

Как ещё можно было бы, я думаю: создать Row определённой ширины, добавлять в него кнопки и следить за суммой ширины кнопок, если ширина кнопок (с учётом margin конечно) на следующей итерации больше ширины Row то создавать следующий Row и так далее. Опять же, я не представляю как это сделать на практике. С model->view всё было как-то проще.

2

Do you like it? Share on social networks!

3
Evgenii Legotckoi
  • July 27, 2020, 6:31 p.m.
  • (edited)
  • The answer was marked as a solution.

Полагаю, что нужно использовать Repeater. Он может формировать объекты из модели. Если добавлять и убирать объекты в модели, то по идее Repeater должен перестраивать объекты во flow.

Здесь уже обсуждался кейс, подобный вашему - ссылка на сообщение

    М
    • July 27, 2020, 7:01 p.m.

    Класс, похоже то что надо, спасибо.

      М
      • July 28, 2020, 1:52 a.m.

      Что-то не получалось, собирался задать вопрос, но вроде разобрался. Пока разбирался сделал кракозябру из кода по ссылке и кода из урока QML - Урок 007. ListView Qml . Не пропадать же добру, пусть будет.

      Пояснение: добавил к примеру ListView Qml --> Flow с Repeater'ом. Оба подсосаны к одной модели и в таком виде без ругани работают (пока что) как ожидается.

      А вопрос на котором споткнулся решился тем что в репитере text: model.text заменил на text: modelData

      qml_flow

      1. import QtQuick 2.12
      2. import QtQuick.Window 2.12
      3. import QtQuick.Controls 2.12
      4.  
      5. Window {
      6. id: window
      7. visible: true
      8. width: 640
      9. height: 480
      10. title: qsTr("Hello World")
      11.  
      12. // Number of Button used in text_button
      13. property int number_of_button: 0
      14.  
      15. // Строка с полем где отображается индекс нажатой кнопки
      16. Row {
      17. id: row
      18. height: 50
      19. anchors.top: parent.top
      20. anchors.left: parent.left
      21. anchors.right: parent.right
      22.  
      23. //Задаём размещение поля с индексом кнопки
      24. Rectangle {
      25. width: ( parent.width / 5)
      26. height: 50
      27.  
      28. // Установливаем текстовое поле для размещения индекса кнопки
      29. Text {
      30. id: textField_For_Button_Id
      31. anchors.fill: parent
      32. text: ""
      33. verticalAlignment: Text.AlignVCenter
      34. horizontalAlignment: Text.AlignHCenter
      35. }
      36. }
      37.  
      38. // Кнопка для создания динамических кнопок
      39. Button {
      40. id: button_Creation
      41. text: qsTr("Create Button")
      42. width: (parent.width / 5) * 2
      43. height: 50
      44.  
      45.  
      46. // По клику на эту кнопку
      47. // в модель
      48. // добавляется объект
      49. // с заданными параметрами
      50. onClicked: {
      51. model_id.append({property_Text_Of_New_Button: "Button " + ( ++number_of_button)})
      52. }
      53. }
      54.  
      55. // Кнопка для удаления динамических кнопок
      56. Button {
      57. id: button_Deletion
      58. text: qsTr("Delete Button")
      59. width: (parent.width / 5) * 2
      60. height: 50
      61.  
      62. // Удаляем кнопку по её индексу в ListView
      63. onClicked: {
      64. if(textField_For_Button_Id.text != "") {
      65. model_id.remove(textField_For_Button_Id.text)
      66. textField_For_Button_Id.text = ""
      67. }
      68. }
      69. }
      70. }
      71.  
      72. // Наша модель, которая используется и для ListView
      73. // и для qml flow type
      74. ListModel {
      75. id: model_id
      76. }
      77.  
      78. // ListView это список
      79. ListView {
      80. id: listView_id
      81. model: model_id // Модель прописана тут!
      82. anchors.top: row.bottom
      83. anchors.bottom: parent.bottom
      84. anchors.left: parent.left
      85. anchors.right: parent.right
      86.  
      87. // Можно было прописать Item тут.
      88. // Вынесли в component и ссылаемся на его id.
      89. delegate: component_id
      90. }
      91.  
      92. Component {
      93. // Вёрстка ОДНОГО объекта
      94. // который отображается в СПИСКЕ
      95. // в качестве одного ЭЛЕМЕНТА списка
      96. id: component_id
      97. Item {
      98. id: item_id
      99. anchors.left: parent.left
      100. anchors.right: parent.right
      101. height: 40
      102.  
      103. // в этом ЭЛЕМЕНТЕ будет одна кнопка
      104. Button {
      105. anchors.fill: parent
      106. anchors.margins: 5
      107.  
      108. // _"самое интересное"_
      109. // задаём свойству text переменную
      110. text: property_Text_Of_New_Button
      111.  
      112. // по клику
      113. // отдаём в текстовое поле
      114. // ListView-индекс элемента
      115. onClicked: {
      116. textField_For_Button_Id.text = index
      117. }
      118. }
      119. }
      120. }
      121.  
      122. Flow {
      123. anchors.bottom: parent.bottom
      124. anchors.horizontalCenter: parent.horizontalCenter
      125. anchors.margins: 4
      126. spacing: 10
      127.  
      128. Repeater {
      129. model: model_id
      130. Rectangle {
      131. width: textMetrics_id.tightBoundingRect.width + 20
      132. height: textMetrics_id.tightBoundingRect.height + 10
      133. color: "gray";
      134. radius: 5;
      135. Text {
      136. id: currentText_id
      137. anchors.centerIn: parent
      138. text: modelData;
      139. }
      140. TextMetrics {
      141. id: textMetrics_id
      142. font: currentText_id.font
      143. text: currentText_id.text
      144. }
      145. }
      146. }
      147. }
      148. }

        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