将数据提供给 ChartView (LineSeries) - QML
Give data to a ChartView (LineSeries) - QML
我最近开始使用QML,我正在寻找一种将数据从c ++提供给QML中的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"
}
}
机器人.h:
class Robot: public QObject
{
...
Q_PROPERTY(QMap<int, double> list_battery_voltages READ getList_battery_voltages NOTIFY listBatteryVoltagesChanged)
...
}
主.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();
}
我正在监督哪些优雅的解决方案?
我已经使用 QVariantMap
解决了它。这不是最优雅的解决方案,但它:)我的 QML 文件中有一个 javascript 函数来填充行序列。此功能连接到我的机器人信号,当新数据到达时将发送该信号。
机器人.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])
}
}
...
}
我
记得QML中的Javascript仅使用QVariantList
和QVariantMap
对数组C++进行操作。在我看来,它们对你都没有好处。因此,我建议您以您喜欢的方式将地图存储在C++中,并提供一些方便的方式来访问值。例如,使用单例:
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;
};
我的辛格尔顿.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;
}
注册(主要.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));
}
}
}
}
使用这种方式可以为您提供一些额外的优势,例如数据更改信号等。
相关文章:
- 从C++实例化QML
- 使用CMake创建QML插件
- QT通过C++添加映射QML项目
- 如何在没有信号的情况下从C++执行QML插槽
- QML按钮点击功能执行顺序
- QML:修改在不同QML文件(而非main.QML)中定义的子对象的属性
- 建议在运行时将带有类实例的列表从c++导入qml
- Qt Quick-如何仅从c++代码与qml属性交互
- 如何将带有自定义对象的容器从C++传递到QML
- QML 使用带有参数C++函数
- 最佳做法是从另一个线程访问 qml 中的Q_PROPERTY
- 如何从C++端挂接到 QML 项的 onClick 事件
- 在 qml 中使用 Q_ENUM 和 Q_PROPERTY 作为枚举类
- 从C++更改 QML 图像源
- QML TableView 使用 QtQuick.Controls 2 单击行
- 如何多次询问来自QML对话框的输入?
- QtQuick - qml:28:错误:未知方法返回类型:自定义类型
- 阅读 QML 中结构C++ QVector 的 QVector
- 如何使用connect将qml按钮与同一类的cpp函数连接起来
- 将数据提供给 ChartView (LineSeries) - QML