Qt 模型视图编程之可编辑数据模型

背景

Qt 模型视图编程中模型定义了标准接口对数据进行访问,可根据需求继承对应的抽象模型类来实现自定义的数据模型。一个基本的数据模型至少要实现以下虚函数:

①.rowCount:行数,返回要显示多少行;

②.columnCount:列数,返回要显示多少列

③.data:读取数据,返回每个单元格要显示的内容

可编辑数据模型

①.概念

视图通过标准接口获取数据并定义显示方式;视图不会主动更新数据的显示,模型使用信号与槽机制通知视图数据变化。

②.关键虚函数

flags:返回该数据项是否可被编辑的标记

setData:模型对外提供的可进行数据修改的接口

③.数据变化信号

dataChanged:信号参数为数据变化的起始和结束范围,使用信号通知视图数据变化。

④.数据项角色

在数据读取接口 data 中,使用 Qt::EditRole 来设置数据编辑时的默认值。

在视图中修改数据

①.TableModelDemo.h 文件

#include 

struct student
{
  QString name;
  int age;
  QString sex;
};//测试用数据结构
Q_DECLARE_METATYPE(student)

class TableModelDemo : public QAbstractTableModel
{
  Q_OBJECT

public:
  TableModelDemo(QList<student> & list, QObject *parent = nullptr):QAbstractTableModel(parent),m_list(list){};
  ~TableModelDemo() {};
protected:
  virtual int rowCount(const QModelIndex &parent) const override;//
  virtual int columnCount(const QModelIndex &parent) const override;//
  virtual QVariant data(const QModelIndex &index,int role) const override;//
  virtual Qt::ItemFlags flags(const QModelIndex &index)const override;//
  virtual bool setData(const QModelIndex &index,const QVariant & value, int role = Qt::EditRole)  override;//
private:
  QList<student> &m_list;//对内存中数据的引用
};
②.TableModelDemo.cpp 文件

int TableModelDemo::rowCount(const QModelIndex &parent) const
{
  return  m_list.size();
}
int TableModelDemo::columnCount(const QModelIndex &parent) const
{
  return 3;
}
QVariant TableModelDemo::data(const QModelIndex &index, int role) const
{
  switch (role)
  {
  case Qt::DisplayRole:
  case Qt::EditRole://数据编辑时的默认值
    {
      int r = index.row();
      int c = index.column();
      switch (c)
      {
      case 0:
        return m_list[r].name;
        break;
      case 1:
        return m_list[r].age;
        break;
      case 2:
        return m_list[r].sex;
        break;
      default:
        break;
      }
    }
    
    break;
  default:
    return QVariant();
    break;
  }
}
Qt::ItemFlags TableModelDemo::flags(const QModelIndex &index) const
{
  return QAbstractTableModel::flags(index) | Qt::ItemIsEditable;
}
bool TableModelDemo::setData(const QModelIndex & index, const QVariant & value, int role) 
{
  
  switch (role)
  {
    case Qt::EditRole:
    {
      int r = index.row();
      int c = index.column();
      switch (c)
      {
      case 0:
        m_list[r].name = value.toString();
        break;
      case 1:
        m_list[r].age = value.toInt();
        break;
      case 2:
        m_list[r].sex = value.toString();
        break;
      default:
        break;
      }
    }
    emit dataChanged(index, index);
    return true;
  default:
    break;
  }
  return true;
}

③.使用自定义模型

QList<student> m_list;//全局数据

student s;
s.age = 18;
s.name = "张三";
s.sex = "男";
m_list.append(s);

s.age = 16;
s.name = "李四";
s.sex = "女";
m_list.append(s);

auto mode = new TableModelDemo(m_list);

ui.tableView->setModel(mode);
ui.tableView_2->setModel(mode);

Qt 模型视图编程之可编辑数据模型_第1张图片

如上图所示,当在视图1 中编辑数据后,在视图2 中自动同步更新显示编辑结果。

在内存中修改数据

①.概念

在应用程序中可以直接在界面进行数据的编辑来修改内存中数据;也会有在另外的过程直接修改内存数据,然后通知界面进行显示。

②.视图数据更新

视图不会主动更新数据的显示,必须通过信号通知视图数据发生变化。

③.代码示例

在按钮单击事件中模拟修改内存数据

connect(ui.pushButton, &QPushButton::clicked, [mode]() {

    m_list[0].age = 28;
    auto index = mode->index(0, 1, QModelIndex());
    emit mode->dataChanged(index, index);//通知视图显示
});

Qt 模型视图编程之可编辑数据模型_第2张图片

Qt 模型视图编程之可编辑数据模型_第3张图片

你可能感兴趣的:(Qt,qt,开发语言)