我最近开始使用QML,我正在寻找一种方法,用QML将数据从c ++提供给我的ChartView。 我更喜欢一个解决方案,我可以发送一个类似Q_PROPERTY的QMap,以便自动更新。
我搜索过并发现你可以执行一个函数,然后你可以使用'append()'将值添加到图表中。但我似乎无法向QML发送某种列表...
QML文件:
ChartView {
theme: ChartView.ChartThemeQt
antialiasing: true
DateTimeAxis {
id: dateTimeAxisX
}
ValueAxis{
id: valueAxisY
min: 0
max: 15
titleText: "Voltage (V)"
}
LineSeries {
id: voltageSeries
axisX: dateTimeAxisX
axisY: valueAxisY
name: "Battery Voltage"
}
}
robot.h:
class Robot: public QObject
{
...
Q_PROPERTY(QMap<int, double> list_battery_voltages READ getList_battery_voltages NOTIFY listBatteryVoltagesChanged)
...
}
main.cpp中:
int main(int argc, char *argv[])
{
#if defined(Q_OS_WIN)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QApplication app(argc, argv);
QQmlApplicationEngine engine;
// Load custom class inside engine
QScopedPointer<Robot> robot(new Robot(app.applicationDirPath() + "/robot_settings.ini"));
engine.rootContext()->setContextProperty("robot", robot.data());
QQmlComponent component(&engine, QUrl(QLatin1String("qrc:/main.qml")));
component.create();
return app.exec();
}
我有监督的优雅解决方案吗?
答案 0 :(得分:1)
我已使用QVariantMap
解决了这个问题。它不是最优雅的解决方案,但它的工作原理:)
我的QML文件中有一个javascript函数可以填充lineseries。
此功能连接到我的机器人信号,当新数据到达时将发送该信号。
robot.h:
class Robot: public QObject
{
...
Q_PROPERTY(QVariantMap list_battery_voltages READ getList_battery_voltages NOTIFY listBatteryVoltagesChanged)
...
}
QML:
ChartView {
...
Connections {
target: robot
onMapBatteryVoltagesChanged: insertVoltages()
}
Component.onCompleted: {
insertVoltages()
}
...
function insertVoltages() {
var voltages_map = robot.map_battery_voltages
for (var prop in voltages_map) {
voltageSeries.append(prop, voltages_map[prop])
}
}
...
}
答案 1 :(得分:0)
我记得QML中的Javascript只使用QVariantList
和QVariantMap
来运行C ++数组。正如我所见,它们对你都不好。因此,我建议您以您喜欢的方式将您的地图存储在C ++中,并提供一些方便的方法来访问这些值。例如,使用singleton:
<强> mysingleton.h 强>
class MySingleton : public QObject
{
Q_OBJECT
public:
explicit MySingleton(QObject *parent = nullptr);
Q_INVOKABLE int count();
Q_INVOKABLE double getX(int index);
Q_INVOKABLE double getY(int index);
private:
QList<QPair<double, double>> m_map;
};
<强> mysingleton.cpp 强>
MySingleton::MySingleton(QObject *parent) : QObject(parent)
{
QRandomGenerator *generator = QRandomGenerator::global();
int count = generator->generate() % 10;
double xAccumulated = 0;
for(int i = 0;i < count;i ++)
{
double x = generator->generateDouble() / (double)count;
xAccumulated += x;
double y = generator->generateDouble();
m_map.append(QPair<double, double>(xAccumulated, y));
}
}
int MySingleton::count()
{
return m_map.count();
}
double MySingleton::getX(int index)
{
return m_map.at(index).first;
}
double MySingleton::getY(int index)
{
return m_map.at(index).second;
}
注册(main.cpp):
static QObject *my_singleton_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
{
return new MySingleton(engine);
}
main() {
qmlRegisterSingletonType<MySingleton>("Qt.MyTest", 1, 0, "MySingleton", my_singleton_provider);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
}
现在你可以在QML中使用它了:
import QtQuick 2.9
import QtCharts 2.1
import Qt.MyTest 1.0
ChartView {
anchors.fill: parent
LineSeries {
id: series
Component.onCompleted: {
for(var i = 0;i < MySingleton.count();i ++) {
series.append(MySingleton.getX(i), MySingleton.getY(i));
}
}
}
}
使用这种方式可以为您提供一些额外的优势,如数据更改信号等。