如何为不同的 setContextProperties 干净地将 C++ 后端对象公开给 QML?
How to cleanly expose C++ backend objects to QML, for varying setContextProperties?
我正在创建一个带有 C++ 后端的 QML 应用程序。不同类型的相机可以连接到我的 C++ 后端。这些相机具有不同类型的传感器和不同数量的电池等。根据连接的相机类型,C++ 后端使用 setContextProperty()
.
将对象公开给 QML
由于我目前使用的方法,我必须在 QML 中检查连接了哪种相机 (camInfo.type
),并根据此绑定到适当的后端对象。这在我的整个 QML 应用程序中都在使用,因此完成了很多开关外壳,并且支持新相机模型非常难以维护。
对于每个不同的相机型号,是否有另一种方法可以将不同的后端对象公开给 QML?我不想在 QML 中的 camInfo.type
上使用任何开关盒。
如果我能做这样的事情就更好了:
Text {
y: 50
x: 50
text: camera.sensor0Data.sensorReading
}
}
其中 camera.sensor0Data.sensorReading
会以某种方式 "map" 到后端中的 apertureData.sensorReading
、sensor0Data.sensorReading
等之一。如果连接的相机不包含该特定传感器,则 Text
将是 visible:false
。
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;
}
}
根据 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 的回答,我会将他的回答标记为已接受。
点赞class
class Camera: public QObject {
Q_PROPERTY (SensorsModel sensors READ sensors NOTIFY sensorsChanged())
};
其中 SensorsModel
可以是一个简单的 QAbstractListModel
暴露一堆传感器对象,比如 Sensor { type: "battery"; minValue: 0; maxValue: 100; value: 50}
.
然后在 QML 中,您可以 Loader
根据相机类型加载各种视图。
我正在创建一个带有 C++ 后端的 QML 应用程序。不同类型的相机可以连接到我的 C++ 后端。这些相机具有不同类型的传感器和不同数量的电池等。根据连接的相机类型,C++ 后端使用 setContextProperty()
.
由于我目前使用的方法,我必须在 QML 中检查连接了哪种相机 (camInfo.type
),并根据此绑定到适当的后端对象。这在我的整个 QML 应用程序中都在使用,因此完成了很多开关外壳,并且支持新相机模型非常难以维护。
对于每个不同的相机型号,是否有另一种方法可以将不同的后端对象公开给 QML?我不想在 QML 中的 camInfo.type
上使用任何开关盒。
如果我能做这样的事情就更好了:
Text {
y: 50
x: 50
text: camera.sensor0Data.sensorReading
}
}
其中 camera.sensor0Data.sensorReading
会以某种方式 "map" 到后端中的 apertureData.sensorReading
、sensor0Data.sensorReading
等之一。如果连接的相机不包含该特定传感器,则 Text
将是 visible:false
。
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;
}
}
根据 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 的回答,我会将他的回答标记为已接受。
点赞class
class Camera: public QObject {
Q_PROPERTY (SensorsModel sensors READ sensors NOTIFY sensorsChanged())
};
其中 SensorsModel
可以是一个简单的 QAbstractListModel
暴露一堆传感器对象,比如 Sensor { type: "battery"; minValue: 0; maxValue: 100; value: 50}
.
然后在 QML 中,您可以 Loader
根据相机类型加载各种视图。