Какие быстрые элементы управления Qt я должен использовать для этого предложенного интерфейса?

Я относительно новичок в QML и Qt Quick и ищу рекомендации по отображению интерфейса здесь:

Этот интерфейс был сделан с помощью QGraphicWidgets с использованием Json в качестве модели:

Если вы заметили, внешний контейнер "Carriage Strength" в основном представляет собой древовидную структуру. Древовидный список кажется подходящим вариантом, но я не уверен, смогу ли я настроить представление так, чтобы оно содержало индикатор выполнения и представление html (QWebEngineView). Мне также нужно будет иметь возможность обновлять определенные компоненты, такие как индикатор выполнения во время выполнения.

Любой вклад полезен. Если у вас есть примеры, на которые можно было бы указать Заранее спасибо.

Как указано ниже, здесь приведен пример JSON, который будет использоваться для построения модели:

{ 
 "SequenceHistory": [
        {
            "Definition": {
                "ID": "carriage_strength",
                "DisplayName": "Carriage Strength",
                "TestArray": [
                    {
                        "ID": "sequence_one_setup",
                        "DisplayName": "Sequence 1 Setup",
                        "TestArray": [
                            {
                                "ID": "psm1_carriage_strength",
                                "DisplayName": "PSM1 Carriage Strength",
                                "Progress":  100,
                                "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                                "Status":  "Finish Failed",
                            },
                            {
                                "ID": "psm2_carriage_strength",
                                "DisplayName": "PSM2 Carriage Strength",
                                "Progress":  43,
                                "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                                "Status":  "In Progress"
                            },
                            {
                                "ID": "psm3_carriage_strength",
                                "DisplayName": "PSM3 Carriage Strength",
                                "Progress":  0,
                                "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                                "Status":  "Not Started"
                            },
                            {
                                "ID": "psm4_carriage_strength",
                                "DisplayName": "PSM4 Carriage Strength",
                                "Progress":  0,
                                "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                                "Status":  "Not Started"
                            }
                        ],
                    },

                ],
            }

    }

    ]
}

Отображаемое имя указывает на имя, ход выполнения указывает на процент выполнения строки, HTML-код указывает HTML-код, отображаемый в WebEngineView, а статус указывает на метку состояния. Не обращайте внимания на информацию о времени, которая есть на скриншоте, но не в JSON. Основное различие между этим JSON и снимком экрана состоит в том, что я добавил контейнер "Настройка последовательности 1" внутри контейнера Carriage Strength, чтобы показать, что контейнеры могут содержать как контейнеры, так и элементы.

1 ответ

Решение

Я широко использую такие элементы GUI, и подход всегда состоит в том, чтобы представлять дерево в виде списков списков, то есть, в зависимости от варианта использования, либо ListView или равнина Repeater с контейнером строки или столбца внутри Flickable и тогда это просто вложение делегата.

Акции TreeView может также его обрезать, если вам не нужен доступ для тонкой настройки и настройки вида.

Лично я столкнулся со слишком большой жесткостью со многими из средств управления запасами, они просто не работают так, как мне нужно, или совершенно не нужной функциональности, и, если это не что-то действительно стандартное, я предпочитаю развернуть свой собственный реализации, что на самом деле довольно легко в QML.

Обновить:

Хорошо, теперь, когда вы предоставили пример источника данных, я могу сделать базовый макет для вас. Кстати, вам не хватает некоторых запятых в JSON, и даже если в моем примере он определен in-line, вы можете просто использовать JSON.parse(text) чтобы получить тот же объект из строки. Также обратите внимание, что modelData в каждой вложенной модели ссылается на отдельный объект данных, в основном на соответствующий индекс элемента массива. А поскольку только в одном из ваших массивов имеется более одного элемента, в целях краткости пример пропускает один уровень:

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

  property var jsondata: {
    "SequenceHistory": [
          {
            "Definition": {
              "ID": "carriage_strength",
              "DisplayName": "Carriage Strength",
              "TestArray": [
                {
                  "ID": "sequence_one_setup",
                  "DisplayName": "Sequence 1 Setup",
                  "TestArray": [
                    {
                      "ID": "psm1_carriage_strength",
                      "DisplayName": "PSM1 Carriage Strength",
                      "Progress":  100,
                      "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                      "Status":  "Finish Failed"
                    },
                    {
                      "ID": "psm2_carriage_strength",
                      "DisplayName": "PSM2 Carriage Strength",
                      "Progress":  43,
                      "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                      "Status":  "In Progress"
                    },
                    {
                      "ID": "psm3_carriage_strength",
                      "DisplayName": "PSM3 Carriage Strength",
                      "Progress":  0,
                      "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                      "Status":  "Not Started"
                    },
                    {
                      "ID": "psm4_carriage_strength",
                      "DisplayName": "PSM4 Carriage Strength",
                      "Progress":  0,
                      "HtmlToDisplay": "<html><body>This is guide instruction</body></html>",
                      "Status":  "Not Started"
                    }
                  ],
                },                    
              ],
            }                
          }              
        ]
  }

  ListView {
    id: rv
    anchors.fill: parent
    model: jsondata.SequenceHistory
    delegate: Rectangle {
      width: rv.width
      height: childrenRect.height // fit the expanding part
      color: "grey"
      Column {
        spacing: 2
        Row {
          spacing: 10
          Button {
            id: exp
            checkable: true
            text: checked ? "+" : "-"
            implicitWidth: 20
            implicitHeight: 20
          }
          Text {
            text: modelData.Definition.DisplayName
            anchors.verticalCenter: parent.verticalCenter
          }
        }
        Column {
          x: 20
          spacing: 2
          Repeater {
            // if not expanded model is null else skip one level
            model: exp.checked ? 0 : modelData.Definition.TestArray[0].TestArray
            delegate: Rectangle {
              width: rv.width
              height: childrenRect.height
              color: "lightgrey"
              Column {
                Row {
                  spacing: 10
                  Button {
                    id: exp2
                    checkable: true
                    text: checked ? "+" : "-"
                    implicitWidth: 20
                    implicitHeight: 20
                  }
                  ProgressBar {
                    value: modelData.Progress
                    from: 1
                    to: 100
                    anchors.verticalCenter: parent.verticalCenter
                  }
                  Text {
                    text: modelData.DisplayName
                    anchors.verticalCenter: parent.verticalCenter
                  }
                }
                Column {
                  visible: exp2.checked // hide if not expanded
                  TextArea {
                    width: 300
                    height: 200
                    text: modelData.HtmlToDisplay
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

И результат:

Обратите внимание, что вы также можете разделить вещи, распределяя делегатов по разным источникам, потому что, по мере того как вы стилизуете их свойства, они будут увеличиваться. Я поместил это в один источник только для примера.

Другие вопросы по тегам