М
МаркГлен27 июля 2020 г. 17:35

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

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("Hello World")

    Flow {
           id: flow_id
           anchors.top: parent.top
           anchors.horizontalCenter: parent.horizontalCenter
           anchors.margins: 4
           spacing: 10
           width: parent.width/1.5

           Button {
               id: first_button
               Text {
                   id: first_button_text
                   text: "Text"
                   font.pointSize: 15
                   anchors.horizontalCenter: parent.horizontalCenter
                   anchors.verticalCenter: parent.verticalCenter
                   verticalAlignment: Text.AlignVCenter
                   horizontalAlignment: Text.AlignHCenter
               }
               width: first_button_text.width + 12
           }
           Button { text: "items"; font.pointSize: 15 }
           Button { text: "flowing"; font.pointSize: 15 }
           Button { text: "inside"; font.pointSize: 15 }
           Button { text: "a"; font.pointSize: 15 }
           Button { text: "Flow"; font.pointSize: 15 }
           Button { text: "item"; font.pointSize: 15 }
       }


}

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

Рекомендуем хостинг TIMEWEB
Рекомендуем хостинг TIMEWEB
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

3
Evgenii Legotckoi
  • 27 июля 2020 г. 18:31
  • (ред.)
  • Ответ был помечен как решение.

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

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

    М
    • 27 июля 2020 г. 19:01

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

      М
      • 28 июля 2020 г. 1:52

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

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

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

      qml_flow

      import QtQuick 2.12
      import QtQuick.Window 2.12
      import QtQuick.Controls 2.12
      
      Window {
          id: window
          visible: true
          width: 640
          height: 480
          title: qsTr("Hello World")
      
          // Number of Button used in text_button
          property int number_of_button: 0
      
          // Строка с полем где отображается индекс нажатой кнопки
          Row {
              id: row
              height: 50
              anchors.top: parent.top
              anchors.left: parent.left
              anchors.right: parent.right
      
              //Задаём размещение поля с индексом кнопки
              Rectangle {
                  width: ( parent.width / 5)
                  height: 50
      
                  // Установливаем текстовое поле для размещения индекса кнопки
                  Text {
                      id: textField_For_Button_Id
                      anchors.fill: parent
                      text: ""
                      verticalAlignment: Text.AlignVCenter
                      horizontalAlignment: Text.AlignHCenter
                  }
              }
      
              // Кнопка для создания динамических кнопок
              Button {
                  id: button_Creation
                  text: qsTr("Create Button")
                  width: (parent.width / 5) * 2
                  height: 50
      
      
                  // По клику на эту кнопку
                  // в модель
                  // добавляется объект
                  // с заданными параметрами
                  onClicked: {
                      model_id.append({property_Text_Of_New_Button: "Button " + ( ++number_of_button)})
                  }
              }
      
              // Кнопка для удаления динамических кнопок
              Button {
                  id: button_Deletion
                  text: qsTr("Delete Button")
                  width: (parent.width / 5) * 2
                  height: 50
      
                  // Удаляем кнопку по её индексу в ListView
                  onClicked: {
                      if(textField_For_Button_Id.text != "") {
                          model_id.remove(textField_For_Button_Id.text)
                          textField_For_Button_Id.text = ""
                      }
                  }
              }
          }
      
          // Наша модель, которая используется и для ListView
          // и для qml flow type
          ListModel {
              id: model_id
          }
      
          // ListView это список
          ListView {
              id: listView_id
              model: model_id // Модель прописана тут!
              anchors.top: row.bottom
              anchors.bottom: parent.bottom
              anchors.left: parent.left
              anchors.right: parent.right
      
              // Можно было прописать Item тут.
              // Вынесли в component и ссылаемся на его id.
              delegate: component_id
          }
      
          Component {
              // Вёрстка ОДНОГО объекта
              // который отображается в СПИСКЕ
              // в качестве одного ЭЛЕМЕНТА списка
              id: component_id
              Item {
                  id: item_id
                  anchors.left: parent.left
                  anchors.right: parent.right
                  height: 40
      
                  // в этом ЭЛЕМЕНТЕ будет одна кнопка
                  Button {
                      anchors.fill: parent
                      anchors.margins: 5
      
                      // _"самое интересное"_
                      // задаём свойству text переменную
                      text: property_Text_Of_New_Button
      
                      // по клику
                      // отдаём в текстовое поле
                      // ListView-индекс элемента
                      onClicked: {
                          textField_For_Button_Id.text = index
                      }
                  }
              }
          }
      
          Flow {
              anchors.bottom: parent.bottom
              anchors.horizontalCenter: parent.horizontalCenter
              anchors.margins: 4
              spacing: 10
      
              Repeater {
                  model: model_id
                  Rectangle {
                      width: textMetrics_id.tightBoundingRect.width + 20
                      height: textMetrics_id.tightBoundingRect.height + 10
                      color: "gray";
                      radius: 5;
                      Text {
                          id: currentText_id
                          anchors.centerIn: parent
                          text: modelData;
                      }
                      TextMetrics {
                          id:     textMetrics_id
                          font:   currentText_id.font
                          text:   currentText_id.text
                      }
                  }
              }
          }
      }
      

        Комментарии

        Только авторизованные пользователи могут публиковать комментарии.
        Пожалуйста, авторизуйтесь или зарегистрируйтесь
        Ua

        Qt - Тест 001. Сигналы и слоты

        • Результат:84баллов,
        • Очки рейтинга4
        Ua

        Qt - Тест 001. Сигналы и слоты

        • Результат:42баллов,
        • Очки рейтинга-8
        ОК

        Qt - Тест 001. Сигналы и слоты

        • Результат:47баллов,
        • Очки рейтинга-6
        Последние комментарии
        ИМ
        Игорь Максимов22 ноября 2024 г. 21:51
        Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
        Evgenii Legotckoi
        Evgenii Legotckoi31 октября 2024 г. 23:37
        Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
        A
        ALO1ZE19 октября 2024 г. 17:19
        Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
        ИМ
        Игорь Максимов5 октября 2024 г. 16:51
        Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
        d
        dblas55 июля 2024 г. 20:02
        QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
        Сейчас обсуждают на форуме
        f
        firstlunoxod15 февраля 2025 г. 13:46
        Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
        Дмитрий
        Дмитрий3 февраля 2025 г. 16:24
        Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
        NW
        Nayo Wai30 января 2025 г. 19:22
        не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
        n
        nkly3 января 2025 г. 12:52
        Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
        M
        Marsel17 августа 2023 г. 0:26
        OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

        Следите за нами в социальных сетях