-1

So, I'm developing a Qt Quick (QML) application, and I have this particular task:

The app will handle different kinds of devices, and not all devices have the same characteristics. For example, since these are SDR devices, one can need one gain slider, while the other has 3 independent ones.

The backend will read the device and know this information: how many stages there are and what are their ranges. So I need my view to create/destroy/readjust sliders as needed.

What is the cleanest way to achieve this kind of think? Accessing QML elements directly from C++ seems to be very discouraged.

Rui Oliveira
  • 606
  • 8
  • 20

2 Answers2

1

There's not much information to go off here, so my answer will be mostly untested pseudo-code.

Updated answer after reading your comment:

I would have a DeviceManager that stores a list of each device that's plugged in. A DeviceModel would listen to changes in that list, and expose a device role (you could also have a role for each property of the device). Create a DeviceUI.qml that represents the common parts of each device, and within that, have a Repeater like @eyllanesc mentioned to enumerate each "gain" type represented by a 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
            }
        }
    }
}

This way, your domain logic knows nothing about the UI (i.e. not accessing QML from C++).

Mitch
  • 23,716
  • 9
  • 83
  • 122
  • Thanks! This is a great start. However, I have an extra requirement. I'm using an "universal" lib, that takes a string as input, so the number of possible devices is "uncountable". Most of the stuff is common, but it's really the number of sliders that can very. So I really need something like "Open device->read device (both in c++) -> tell QML how many sliders and with what ranges" I can't just account for all of them with loaders. – Rui Oliveira Mar 10 '21 at 09:00
  • 1
    OK, then it'd be similar but with one UI for all devices, and a model within that UI that represents the variable amount of sliders. – Mitch Mar 10 '21 at 09:12
0

in generally the configuration always has some determined feature that must have:

  • accessible to every item or object
  • broadcast change event
  • independent from the consumers
  • default values ...

from our personal experience,always we create a c++ singlton object and create the configure values property(QProperty) and send them to the QML engine as a Context Property (QQmlContext::setContextProperty()). all the QML items are binding on the own property. when a config value must be change all the items can aware of this change and after that update yourself.

SajadBlog
  • 514
  • 2
  • 12