以编程方式重新配置 QML 控件

Reconfiguring QML controls programatically

所以,我正在开发一个 Qt Quick (QML) 应用程序,我有这个特殊的任务:

该应用程序将处理不同类型的设备,并非所有设备都具有相同的特性。例如,由于这些是 SDR 设备,一个可以需要一个增益滑块,而另一个有 3 个独立的。

后端将读取设备并知道此信息:有多少个阶段以及它们的范围是多少。所以我需要根据需要查看 create/destroy/readjust 滑块。

实现这种想法的最干净的方法是什么?直接从 C++ 访问 QML 元素似乎非常令人沮丧。

一般来说,配置总是有一些确定的特征,必须有:

  • 每个项目或对象都可以访问
  • 广播更改事件
  • 独立于消费者
  • 默认值 ...

根据我们的个人经验,我们总是创建一个 C++ 单例对象并创建配置值 属性(Q属性) 并将它们作为上下文 属性 发送到 QML 引擎(QQmlContext::setContext属性())。 所有 QML 项目都是自己绑定的 属性。当必须更改配置值时,所有项目都可以知道此更改,然后自己进行更新。

这里没有太多信息,所以我的回答主要是未经测试的伪代码。

阅读您的评论后更新的答案:

我会有一个 DeviceManager 来存储插入的每个设备的列表。DeviceModel 会监听该列表中的变化,并公开一个 device 角色(你也可以为设备的每个 属性 分配一个角色)。创建一个 DeviceUI.qml 代表每个设备的公共部分,并在其中有一个像 @eyllanesc 提到的 Repeater 来枚举由 DeviceGainModel 代表的每个“增益”类型:

// DeviceUi.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 2.15

GroupBox {
    id: root
    title: device.displayName

    required property var device

    ColumnLayout {
        anchors.fill: parent

        Repeater {
            model: DeviceGainModel {
                device: root.device
            }
            delegate: RowLayout {
                Label {
                    text: model.gainDisplayName
                }
                Slider {
                    value: model.gain
                    onMoved: model.gain = value
                }
            }
        }
    }
}

// main.qml
import QtQuick 2.15
import QtQuick.Controls 2.15
import QtQuick.Layouts 2.15

import MyApp 1.0

ApplicationWindow {
    id: window
    width: 640
    height: 480
    visible: true

    required property DeviceManager deviceManager

    ColumnLayout {
        Repeater {
            model: DeviceModel {
                deviceManager: window.deviceManager
            }
            delegate: DeviceUi {
                // Set via model roles.
                required property var device
            }
        }
    }
}

这样,您的域逻辑对 UI 一无所知(即不从 C++ 访问 QML)。