【问题标题】:What Qt Quick Controls should I use for this proposed UI?对于这个提议的 UI,我应该使用哪些 Qt 快速控件?
【发布时间】:2018-12-20 19:49:27
【问题描述】:

我对 QML 和 Qt Quick 比较陌生,我正在寻找有关如何在此处显示 UI 的建议:

这个 UI 是由 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"
                            }
                        ],
                    },

                ],
            }

    }

    ]
}

display name表示名称,progress表示进度条百分比,html表示要在WebEngineView中显示的html,status表示状态标签。忽略屏幕截图中的任何时间信息,而不是 JSON 中的任何时间信息。这个 JSON 和屏幕截图的主要区别在于,我在 Carriage Strength 容器内添加了一个容器“Sequence 1 Setup”,以显示容器可以包含容器以及项目。

【问题讨论】:

  • 我认为 TreeView 有点太受限制了,因为外部级别看起来与内部级别节点不同。但也许你可以通过为某些项目设置可见的 false (如果是外部级别)来摆脱它。这会很方便,因为 TreeView 具有我在任何其他 QML 小部件中都没有找到的扩展概念。你可以在itemDelegate 中扔任何你想要的东西

标签: qt user-interface qml qtreeview


【解决方案1】:

我广泛使用此类 GUI 元素,方法总是将树表示为列表的列表,也就是说,根据用例,ListView 或带有一行的普通 RepeaterFlickable 内的列容器,然后它只是委托嵌套。

股票TreeView 也可以削减它,如果您不需要访问权限来微调和自定义视图。

我个人在使用许多库存控件时遇到了太多的问题,它们只是不能按照我需要的方式工作,或者完全缺乏所需的功能,除非它是真正标准的东西,否则我更喜欢滚动我自己的实现,这在 QML 中实际上很容易。

更新:

好的,既然你已经提供了一个示例数据源,我可以为你做一个基本的模型。顺便说一句,您在 JSON 中缺少一些逗号,即使在我的示例中它是内联定义的,您也可以简单地使用 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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}

结果:

请注意,您还可以通过将委托分散到不同的源来划分事物,因为当您设置它们的属性时,它们会变得更大。为了示例,我将其放在一个来源中。

【讨论】:

  • 感谢您的建议。如果我要推出自己的实现,那会是什么样子?我喜欢模型/视图/委托结构,因为我可以将它与我的 C++ 对象绑定。如果不使用罐装视图,这仍然可能吗?如果您有任何示例代码可以查看,那将非常有帮助。
  • 好吧,如果是标准的JSON,你可以简单的在QML中解析,大概里面有数据数组,可以直接在QML中作为模型使用。也许发布一个示例 JSON 作为数据源。
  • 我继续发布了一些 JSON 示例。谢谢。
  • 谢谢,我会推出自己的实现。我遇到的最大问题是,像“Carriage Strength”和“Sequence 1 Setup”这样的容器项目实际上是列表视图,可以包含像它自己这样的其他列表视图或像“PSM1 Carriage strength”这样的实际项目。我发现似乎可以解决该问题的方法可能是您在此处描述的嵌套模型方法:stackoverflow.com/questions/31996279/… 我知道这要求很多,但是您能否为我的示例演示嵌套模型方法?
  • 我想改用符合嵌套模型方法的 C++ 模型。谢谢。
猜你喜欢
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-03
相关资源
最近更新 更多