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

如何用QML与C++实现多独立数据TableView(绑定模型实例)

解决QML中多个独立TableModel实例的问题

你的问题根源在于当前的TableModel类没有为每个实例维护独立的数据源,导致所有表格共享同一套数据逻辑。下面是具体的实现方案:

1. 修改C++ TableModel类,添加实例化数据存储

让每个TableModel实例拥有自己的数据集合,并提供接口设置/更新数据,同时正确实现模型的视图通知机制。

修改后的tablemodel.h

#ifndef TABLEMODEL_H
#define TABLEMODEL_H

#include "qqmlintegration.h"
#include <QObject>
#include <QAbstractTableModel>
#include <QVector>

class TableModel : public QAbstractTableModel
{
    Q_OBJECT
    QML_ELEMENT
    QML_ADDED_IN_MINOR_VERSION(1)
    // 暴露数据属性,允许QML设置或更新
    Q_PROPERTY(QVector<QVector<QVariant>> modelData READ modelData WRITE setModelData NOTIFY modelDataChanged)
public:
    explicit TableModel(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) const override;
    QHash<int, QByteArray> roleNames() const override;

    QVector<QVector<QVariant>> modelData() const;
    void setModelData(const QVector<QVector<QVariant>> &newData);

    // 单个单元格更新接口
    Q_INVOKABLE void updateCell(int row, int column, const QVariant &value);

signals:
    void modelDataChanged();

private:
    // 每个实例独立的数据存储
    QVector<QVector<QVariant>> m_data;
};

#endif

修改后的tablemodel.cpp

#include "tablemodel.h"

TableModel::TableModel(QObject *parent)
    : QAbstractTableModel(parent)
{
}

int TableModel::rowCount(const QModelIndex &parent) const
{
    if (parent.isValid())
        return 0;
    return m_data.size();
}

int TableModel::columnCount(const QModelIndex &parent) const
{
    if (parent.isValid() || m_data.isEmpty())
        return 0;
    return m_data.first().size();
}

QVariant TableModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || role != Qt::DisplayRole)
        return QVariant();

    return m_data[index.row()][index.column()];
}

QHash<int, QByteArray> TableModel::roleNames() const
{
    return {{Qt::DisplayRole, "display"}};
}

QVector<QVector<QVariant>> TableModel::modelData() const
{
    return m_data;
}

void TableModel::setModelData(const QVector<QVector<QVariant>> &newData)
{
    beginResetModel();
    m_data = newData;
    endResetModel();
    emit modelDataChanged();
}

void TableModel::updateCell(int row, int column, const QVariant &value)
{
    if (row < 0 || row >= m_data.size() || column < 0 || column >= m_data[row].size())
        return;

    m_data[row][column] = value;
    emit dataChanged(index(row, column), index(row, column), {Qt::DisplayRole});
}

2. 在QML中创建多个独立的TableModel实例

现在每个TableModel实例可拥有独立数据,你可以直接在QML中初始化不同数据,或从C++传递专属数据源。

修改后的Main.qml

import QtQuick
import QtQuick.Window
import TableModel 0.1

Window {
    width: 800
    height: 600
    visible: true
    title: qsTr("多独立表格示例")

    // 第一个表格
    TableView {
        anchors.top: parent.top
        anchors.left: parent.left
        width: parent.width / 2 - 5
        height: parent.height
        columnSpacing: 1
        rowSpacing: 1
        clip: true

        model: TableModel {
            modelData: [
                ["表格1行1列", "表格1行1列值"],
                ["表格1行2列", "表格1行2列值"],
                ["表格1行3列", "表格1行3列值"]
            ]
        }

        delegate: Rectangle {
            implicitWidth: 150
            implicitHeight: 40
            color: "#f0f0f0"
            border.width: 1
            Text {
                anchors.centerIn: parent
                text: display
            }
        }
    }

    // 第二个表格
    TableView {
        anchors.top: parent.top
        anchors.right: parent.right
        width: parent.width / 2 - 5
        height: parent.height
        columnSpacing: 1
        rowSpacing: 1
        clip: true

        model: TableModel {
            modelData: [
                ["表格2行1列", "表格2行1列值"],
                ["表格2行2列", "表格2行2列值"],
                ["表格2行3列", "表格2行3列值"]
            ]
        }

        delegate: Rectangle {
            implicitWidth: 150
            implicitHeight: 40
            color: "#f0f0f0"
            border.width: 1
            Text {
                anchors.centerIn: parent
                text: display
            }
        }
    }

    // 独立更新示例:更新表格1的单元格
    Button {
        anchors.bottom: parent.bottom
        anchors.horizontalCenter: parent.horizontalCenter
        text: "更新表格1第一行"
        onClicked: {
            table1Model.updateCell(0, 1, "更新后的值")
        }
    }

    TableModel {
        id: table1Model
        modelData: [
            ["表格1行1列", "表格1行1列值"],
            ["表格1行2列", "表格1行2列值"],
            ["表格1行3列", "表格1行3列值"]
        ]
    }
}

3. 关键说明

  • 每个TableModel实例通过m_data成员维护独立数据,彻底解决共享数据问题
  • 全量替换数据时用beginResetModel()/endResetModel()通知视图刷新
  • 单个单元格更新时用dataChanged()做精确通知,提升性能
  • QML可直接通过modelData属性初始化数据,也可在C++中为不同实例绑定专属数据源

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 18:44:49