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

C++ Memory类与QAbstractTableModel数据传输及更新触发方案咨询

实现方案

1. 核心设计思路

采用Qt原生信号槽机制实现无侵入的同步,避免数据冗余拷贝,保证更新实时性:

  • Memory类作为唯一数据源,数据变更时主动发射信号通知关联对象
  • MemoryModel持有Memory实例的只读指针/引用,直接读取数据源渲染表格,不单独存储副本
  • MemoryModel监听Memory的变更信号,调用QAbstractTableModel标准更新接口触发视图刷新

2. 代码修改示例

2.1 修改memory.hpp

// memory.hpp
#include <QObject>
// 让Memory继承QObject以支持信号槽
class Memory : public QObject
{
    Q_OBJECT
public:
    // 原有数据操作接口,比如修改单元格、增删行等
    void updateCell(int row, int col, const QVariant& val);
    void addRow(int rowIndex);
    void removeRow(int rowIndex);
signals:
    // 单元格数据变更信号:参数为行、列
    void cellUpdated(int row, int col);
    // 行添加信号:参数为插入的起始行、结束行
    void rowAdded(int startRow, int endRow);
    // 行删除信号:参数为删除的起始行、结束行
    void rowRemoved(int startRow, int endRow);
    // 批量更新场景可加重置信号
    void dataReset();
private:
    // 原有数据存储成员,比如二维数组、结构体列表等
};

// updateCell实现示例,其他数据修改方法同理
void Memory::updateCell(int row, int col, const QVariant& val) {
    // 原有更新数据的逻辑不变
    // 数据更新完成后发射信号
    emit cellUpdated(row, col);
}

2.2 修改memory_model.hpp

// memory_model.hpp
#include <QAbstractTableModel>
#include "memory.hpp"

class MemoryModel : public QAbstractTableModel
{
    Q_OBJECT
public:
    // 构造函数新增Memory指针参数
    explicit MemoryModel(Memory* mem, 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;
private slots:
    // 接收Memory变更信号的槽函数
    void onCellUpdated(int row, int col);
    void onRowAdded(int startRow, int endRow);
    void onRowRemoved(int startRow, int endRow);
    void onDataReset();
private:
    Memory* m_memory = nullptr; // 持有数据源指针
};

2.3 MemoryModel实现示例

// memory_model.cpp
MemoryModel::MemoryModel(Memory* mem, QObject *parent)
    : QAbstractTableModel(parent), m_memory(mem)
{
    // 绑定Memory的信号到Model的槽函数
    connect(m_memory, &Memory::cellUpdated, this, &MemoryModel::onCellUpdated);
    connect(m_memory, &Memory::rowAdded, this, &MemoryModel::onRowAdded);
    connect(m_memory, &Memory::rowRemoved, this, &MemoryModel::onRowRemoved);
    connect(m_memory, &Memory::dataReset, this, &MemoryModel::onDataReset);
}

int MemoryModel::rowCount(const QModelIndex &parent) const {
    if (parent.isValid() || !m_memory) return 0;
    // 直接返回Memory中的数据行数,替换为你自己的获取行数接口
    return m_memory->getRowCount();
}

int MemoryModel::columnCount(const QModelIndex &parent) const {
    if (parent.isValid() || !m_memory) return 0;
    // 直接返回Memory中的数据列数,替换为你自己的获取列数接口
    return m_memory->getColumnCount();
}

QVariant MemoryModel::data(const QModelIndex &index, int role) const {
    if (!index.isValid() || !m_memory || role != Qt::DisplayRole) return {};
    // 直接从Memory中读取对应位置的数据,替换为你自己的取值接口
    return m_memory->getCellData(index.row(), index.column());
}

// 槽函数实现
void MemoryModel::onCellUpdated(int row, int col) {
    QModelIndex idx = index(row, col);
    emit dataChanged(idx, idx); // 触发单个单元格更新
}

void MemoryModel::onRowAdded(int startRow, int endRow) {
    beginInsertRows(QModelIndex(), startRow, endRow);
    endInsertRows(); // 触发行插入更新
}

void MemoryModel::onRowRemoved(int startRow, int endRow) {
    beginRemoveRows(QModelIndex(), startRow, endRow);
    endRemoveRows(); // 触发行删除更新
}

void MemoryModel::onDataReset() {
    beginResetModel();
    endResetModel(); // 全量刷新表格,仅用于批量更新场景
}

3. 注意事项

  • 所有数据修改操作必须走Memory类的接口,不要直接在Model层修改数据,避免信号漏发导致不同步
  • 非必要不要频繁调用beginResetModel/endResetModel,会导致整个表格重绘、丢失选中状态,优先用局部更新接口
  • 如果Memory类无法继承QObject,可以在Memory中加观察者回调接口,Model实现回调接口注入到Memory中实现变更通知,但信号槽是Qt场景下的最优方案,代码量最少、稳定性最高

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 20:15:06