C++ Qt Programming - 47 - model view
1 data、model、view、Delegate
model:代表全部或部分data
view:展示data,如a list view, a combo box....
delegate:用于编辑数据或展示数据(后续再说)
2 model/view的设置和展示:
Model有自己的set函数,参数是Data;
View有自己的set函数,参数是Model;
多个view可以共享一个model。
model = new QStringListModel(this);
QStringList list;
list << "cats" << "dogs" << "birds"; // 准备data
model->setStringList(list); // model的set函数,参数是data
ui->listView->setModel(model); // view的set函数,参数是model
ui->comboBox->setModel(model); // 共享model
3 双击或输入按键,对所展示的View进行修改(同时也修改了model的数据):
ui->listView->setEditTriggers(QAbstractItemView::AnyKeyPressed | QAbstractItemView::DoubleClicked);
4 增、插、删model中的数据并展示(没有修改功能)
model的常用接口:index()、rowCount()、insertRows()、removeRows() // 其它
view的常用接口:setCurrentIndex()、currentIndex()、edit() // 1)修改具体值;2)视觉上的接口
QModelIndex:model的索引,用于view一些函数的参数
void Dialog::on_pushButton_clicked()
{
// add
int row = model->rowCount();
model->insertRows(row, 1);
QModelIndex index = model->index(row);
ui->listView->setCurrentIndex(index); // 选中当前行
ui->listView->edit(index); // 将listView设为可编辑模式
}
void Dialog::on_pushButton_2_clicked()
{
// insert
int row = ui->listView->currentIndex().row();
model->insertRows(row, 1);
QModelIndex index = model->index(row);
ui->listView->setCurrentIndex(index);
ui->listView->edit(index);
}
void Dialog::on_pushButton_3_clicked()
{
// delete
model->removeRows(ui->listView->currentIndex().row(),1);
}
5 QDirModel和QTreeView(QDirModel已被QFileSystemModel代替)
model = new QDirModel(this);
ui->treeView->setModel(model); // 显示整个文件系统,QDirModel自带有文件系统

QDirModel常用接口:setReadOnly、setSorting // 按文件名进行排序等
QTreeView常用接口:expand、scrollTo、setCurrentIndex、resizeColumnToContents // 展开树、滚动到index位置并选中、第0列内容自适应
问题:已经设置了readonly为什么还能改?
void Dialog::on_pushButton_clicked()
{
// make dir
QModelIndex index = ui->treeView->currentIndex();
if (!index.isValid()) return;
QString name = QInputDialog::getText(this, "Name", "Enter a name"); // 输入框的用法,点击确定,返回输入框的值
if (name.isEmpty()) return;
model->mkdir(index, name);
}
void Dialog::on_pushButton_2_clicked()
{
// delete
QModelIndex index = ui->treeView->currentIndex();
if (!index.isValid()) return;
if (model->fileInfo(index).isDir()) { // 文件或文件夹的判断方法
model->rmdir(index); // 通过index来删除文件或文件夹
} else {
model->remove(index);
}
}
输入框:

6 QFileSystemModel(不会锁GUI,asynchronous异步的)实现文件浏览器:
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
QString sPath = "F:/";
dirModel = new QFileSystemModel(this);
dirModel->setFilter(QDir::NoDotAndDotDot | QDir::AllDirs);
dirModel->setRootPath(sPath); // 必须指定一个rootpath
ui->treeView->setModel(dirModel);
fileModel = new QFileSystemModel(this);
fileModel->setFilter(QDir::NoDotAndDotDot | QDir::Files);
fileModel->setRootPath(sPath); // 必须指定一个rootpath
ui->listView->setModel(fileModel);
}
void Dialog::on_treeView_clicked(const QModelIndex &index)
{
// 取当前选中的treeview的路径,并在右边显示出来
QString sPath = dirModel->fileInfo(index).absoluteFilePath();
ui->listView->setRootIndex(fileModel->setRootPath(sPath));
}

7 QItemDelegate
使用QStandardItemModel和QTableView,目的是为了在QTableView的某个单元格中使用spinbox
这节课有点难,先跳过
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义