什么是Model/View设计模式,该模式解决了什么问题
一个好的有图形界面的应用程序的软件架构应该是显示和数据是分离的,显示部分不应该去处理数据,数据处理部分更不应该去做显示相关的事情。
Qt提供的Model/View设计模式就能很好完成改任务。
其实更好的应该叫做Data/Model/View设计模式。这样能看出这个结构就是Model在Data和View之间提供了一个桥梁,来将数据和显示分离开。
如何显示
Qt提供的这个模式使用起来非常方便,Data部分的代码不需要开发者自己实现,View中的代码也不需要自己去实现,只需要将view和model绑定,data和model绑定,之后仅仅操作Model就可以在View上显示,并且修改Data中的数据。
比如以下代码分别用两个接口将data和model、view和model进行了绑定。这个操作之后不需要其它任何语句UI就能够显示除data的数据了。
QStringListModel *stringListModel_;
QStringList strList;
strList << "item1" << "item2" << "item3" << "item4" << "item5" << "item6";
ui->listView->setModel(stringListModel_);
stringListModel_->setStringList(strList);
如何修改数据
在完成了绑定之后修改数据主要就是通过model来修改了。
在界面上双击item也可以进行修改
在View上除了显示之外,肯定还需要用户交换通过界面去修改数据,往往在界面上双击一个数据,就可以进行编辑了,默认双击数据后,会变为lineEdit使之能够编辑,也可以是spinBox等。这个称之为代理。
代理:定制数据的界面显示和编辑方式
代理就是view上为编辑数据提供的编辑器,缺省值是QLineEdit,
代理负责从Model中获取响应的数据,显示在编辑器里
通过代码获取、修改数据
QT提供以下两个接口用于获取和修改数据
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole)
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
以上接口中role参数,可以为数据model的一项数据设置数据的时候赋予该项不同的角色,这样一个项可以有多个数据。
Model
并不是说所有类型的Data都有已经可以使用的model,不可能有一个Model能适配到任意类型的数据的
model中存储数据的基本单元都是项Item,每个Item有一个行号一个列号,还有一个父项
QModelIndex表示数据模型的索引的类,模型索引提供数据存取的一个临时指针。用QModelIndex可以找到对应的Item
void StringListModel::on_btn_inster_item_in_mode_clicked()
{
QModelIndex index=stringListModel_->index(ui->listView->currentIndex().row()-1,0);
stringListModel_->setData(index, "insert item", Qt::DisplayRole);
}
void StringListModel::on_listView_clicked(const QModelIndex &index)
{
ui->label->setText(QString::asprintf("行 %d, 列 %d",index.row(),index.column()));
}
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole)
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole)
model、view和代理之间通过信号和槽来相互通信。
QStandardItemModel
以项数据为基础的标准数据模型
通常与QTableView组成model view结构,实现通用的二维数据管理功能