I am creating a QML Application with a C++ backend. Different types of cameras can connect to my C++ backend. These cameras have different types of sensors and different numbers of batteries, etc. Depending on what type of Camera is connected, the C++ backend exposes objects to QML using setContextProperty()
.
Due to the method I am currently using, I have to check what kind of camera is connected (camInfo.type
) in QML, and depending on that, bind to the appropriate backend object. This is used throughout my QML Application, so a lot of switch-casing is done, and it is very unmaintainable to support a new camera model.
Is there another way I can expose the varying backend objects to QML, for each different camera model? I do not want to use any switch-cases on camInfo.type
in QML.
It would be preferable if I could do something like:
Text {
y: 50
x: 50
text: camera.sensor0Data.sensorReading
}
}
where camera.sensor0Data.sensorReading
would somehow "map" to one of apertureData.sensorReading
, sensor0Data.sensorReading
etc. in the backend. And the Text
would be visible:false
if the connected camera doesn't include that specific sensor.
Snippet of main.qml
Text {
y: 50
x: 50
text: {
switch(camInfo.type){
case 0: // DSLR
apertureData.sensorReading
break
case 1: //MOBILE
sensor0Data.sensorReading
break
case 2: //PointandShoot
sensor0Data.sensorReading
}
}
}
Text {
visible: camInfo.type==2 // Point and Shoot
y: 90
x: 90
text: {
switch(camInfo.type){
case 0: // DSLR
case 1: //MOBILE
"N/A"
break
case 2: //PointandShoot
microphoneData.sensorReading
}
}
}
backend.cpp
#include "backend.h"
#include <QQmlContext>
enum Model {
// types of cameras.
DSLR=0,
MOBILE_CAMERA,
POINT_AND_SHOOT
};
Backend::Backend(QQmlApplicationEngine* engine, QObject *parent) :
QObject(parent)
{
// Connecting back end object instances to front end
QQmlContext* ctxt(engine->rootContext());
ctxt->setContextProperty("camInfo", deviceInfo);
ctxt->setContextProperty("videoFeedData", videoFeedData); //video.h
switch(deviceInfo->m_type){
case DSLR:
ctxt->setContextProperty("battery0Data", battery0Data); // battery.h
ctxt->setContextProperty("battery1Data", battery1Data); // battery.h
ctxt->setContextProperty("battery2Data", battery2Data); // battery.h
ctxt->setContextProperty("apertureData", apertureData); // aperture.h
ctxt->setContextProperty("sensor1Data", sensor1Data); // sensor.h
ctxt->setContextProperty("sensor2Data", sensor2Data); // sensor.h
ctxt->setContextProperty("sensor3Data", sensor3Data); // sensor.h
break;
case MOBILE_CAMERA:
ctxt->setContextProperty("sensor0Data", sensor0Data); // sensor.h
ctxt->setContextProperty("batteryData", batteryData); // battery.h
break;
case POINT_AND_SHOOT:
ctxt->setContextProperty("microphoneData", microphoneData);
ctxt->setContextProperty("sensor0Data", sensor0Data); // sensor.h
ctxt->setContextProperty("batteryData", batteryData); // battery.h
break;
}
}
As per Dinesh's comment, the idea of using a Loader
to load various views appeared to be the method to move forward with. I am posting his answer here for now, to mark this question as answered. If @Dinesh answers it, I will mark his answer as accepted instead.
Make a class like
class Camera: public QObject {
Q_PROPERTY (SensorsModel sensors READ sensors NOTIFY sensorsChanged())
};
Where SensorsModel
can be a simple QAbstractListModel
exposing a bunch of Sensor objects, something like say Sensor { type: "battery"; minValue: 0; maxValue: 100; value: 50}
.
Then in the QML you can have a Loader
loading various Views based on the camera type.