You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何结合QtGraphs与XYModelMapper?实现模型数据至QML映射

QtGraphs中QAbstractTableModel与XYModelMapper的X/Y值映射方案

一、QML中XYModelMapper的正确配置

从QtCharts迁移到QtGraphs后,XYModelMapper的列映射属性名发生了变化,需替换旧的xSection/ySection为xColumn/yColumn。正确的QML代码如下:

GraphsView {
  antialiasing: true
  anchors.fill: parent
  LineSeries {
    XYModelMapper {
       model: modelname
       // 指定表格模型中X、Y值对应的列索引
       xColumn: 0
       yColumn: 1
    }
 }
}

二、C++模型代码修正

你的GraphsModel存在几处关键错误,导致数据无法被正确读取,以下是修正后的代码:

修正后的Graphsmodel.h

#ifndef GRAPHSMODEL_H
#define GRAPHSMODEL_H

#include <cmath>
#include <QObject>
#include <QAbstractTableModel>  // 替换原QAbstractListModel,与继承类匹配

#define PI 3.14159265359

class GraphsModel : public QAbstractTableModel
{
   Q_OBJECT

public:
    explicit GraphsModel(QObject *parent = nullptr);  // 添加父类指针参数

    int rowCount(const QModelIndex& parent = QModelIndex()) const override;
    int columnCount(const QModelIndex& parent = QModelIndex()) const override;

    QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
    void populate();

private:
    int ncoords;
    std::vector<double> xvalues;
    std::vector<double> yvalues;
    QList<std::pair<double,double>> mDatas;
};

#endif // GRAPHSMODEL_H

修正后的Graphsmodel.cpp

#include "graphsmodel.h"

GraphsModel::GraphsModel(QObject *parent) : QAbstractTableModel(parent)
{
    ncoords = 100;
    xvalues.resize(ncoords);
    yvalues.resize(ncoords);

    for(int icoords = 0; icoords < ncoords; ++icoords){
       xvalues[icoords] = double(5 * icoords) * PI / 180.0;
       yvalues[icoords] = std::sin(xvalues[icoords]);
    }

    populate();
}

int GraphsModel::rowCount(const QModelIndex& parent) const
{
    if (parent.isValid())
        return 0;
    return ncoords;
}

int GraphsModel::columnCount(const QModelIndex& parent) const
{
    if (parent.isValid())
        return 0;
    return 2;
}

QVariant GraphsModel::data(const QModelIndex& index, int role) const
{
    // 仅处理DisplayRole,这是XYModelMapper默认使用的角色
    if (!index.isValid() || role != Qt::DisplayRole)
        return QVariant();

    int row = index.row();
    int column = index.column();

    if(row < 0 || row >= ncoords)
        return QVariant();

    if(column == 0) {
        return mDatas.at(row).first;
    } else if(column == 1) {
        return mDatas.at(row).second;
    }

    return QVariant();
}

void GraphsModel::populate()
{
    // 使用模型重置信号,批量更新数据更可靠
    beginResetModel();
    mDatas.clear();
    for(int icoord = 0; icoord < ncoords; ++icoord){
        mDatas.append(std::make_pair(xvalues[icoord], yvalues[icoord]));
    }
    endResetModel();
}

三、QML代码修正

将原QML中的xSection/ySection替换为xColumn/yColumn,修正后的Main.qml:

import QtQuick
import QtGraphs
import graphsexample

Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    GraphsView {
        antialiasing: true
        anchors.fill: parent
        LineSeries {
            XYModelMapper {
                model: Graphsmodel
                xColumn: 0
                yColumn: 1
            }
        }
    }
}

四、核心问题总结

  1. 属性名变更:QtGraphs的XYModelMapper不再使用QtCharts的xSection/ySection,改用xColumn/yColumn指定列索引,这是数据无法映射的核心原因。
  2. Role处理:必须确保data()函数仅在role == Qt::DisplayRole时返回数据,否则Mapper无法正确读取值。
  3. 模型信号规范:批量更新数据时,使用beginResetModel()和endResetModel()比手动发射dataChanged更安全可靠。
  4. 继承与头文件匹配:继承QAbstractTableModel时,头文件需包含对应的<QAbstractTableModel>。

内容的提问来源于stack exchange,提问作者user24126140

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 19:08:10