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
相关产品推荐
相关产品推荐

