| View | Module |
|---|---|
| listView | QStringListModel |
| tableView | QStandardItemModel QItemSelectionModel |
| treeView | QFileSystemModel |
- View 都是通过
setModel()来绑定模型。 - 我们只需要把数据绑定到Model上就可以了,不同的view使用不同的model,如上图。
- 获取View中的item,是使用 QModelIndex 来获取 index, 然后使用 itemFromIndex。
QModelIndex index = theModel->index(row, column);QStandardItem *item = theModel->itemFromIndex(index);item->setData("内容", Qt::DisplayRole);
1. treeView -> QFileSystemModel
fileModel = new QFileSystemModel(this);fileModel->setRootPath(QDir::currentPath());ui->treeView->setModel(fileModel);ui->listView->setModel(fileModel);ui->tableView->setModel(fileModel);
2. listView -> QStringListModel
setStringList(): 初始化数据模型的字符串列表的内容提供编辑和修改字符串列表数据的函数:
insertRows()removeRows()setData()
显示加载数据:
QStringListModel *theModel = new QStringListModel(this);QStringList strList;for (int i=0; i<6; i++) {strList.append(QString::asprintf("item %d", i));}theModel->setStringList(strList);ui->listView->setModel(theModel);// 可以让listview单元格可编辑ui->listView->setEditTriggers(QAbstractItemView::DoubleClicked| QAbstractItemView::SelectedClicked);
在已有的列表中新加一项:
int lastRow = theModel->rowCount(); // 获取最后一项的rowtheModel->insertRow(lastRow); // 在最后一项添加一个新itemQModelIndex idx = theModel->index(lastRow, 0); // 获取这个row的indextheModel->setData(idx, "new item", Qt::DisplayRole); // 设置值ui->listView->setCurrentIndex(idx); // 设置最后一项被选中
在被选中的地方插入新item:
// 先在model中增加一个itemQModelIndex index = ui->listView->currentIndex(); // 获取被选择中的row的indextheModel->insertRow(index.row()); // 插入一个新item// 再设置这个item的值theModel->setData(index, "insert item", Qt::DisplayRole); // 设置值ui->listView->setCurrentIndex(index); // 设置该item被选中
删除被选中的:
theModel->removeRow(ui->listView->currentIndex().row());
清除所有项:
theModel->removeRows(0, theModel->rowCount());
3. tableView -> QStandardItemModel
以项数据为基础的标准数据模型类,通常与QTableView组合成MV结构,实现通用的二维数据的管理功能。
- 处理二维数据
每个项是一个QStandardItem,用于存储项的:
- 数据
- 字体
- 对齐
- 等
QItemSelectionModel: 跟踪view组件的单元格选中状态的类,通过它可以获得选中的单元格的模型索引。
初始化model并绑定到view:
theModel = new QStandardItemModel(10, 4, this); // 初始化10行4列的modeltheSelection = new QItemSelectionModel(theModel); // 绑定select到modelui->tableView->setModel(theModel); // 绑定viewui->tableView->setSelectionModel(theSelection); // 绑定view// 添加选择后的事件connect(theSelection, SIGNAL(currentChanged(QModelIndex,QModelIndex)),this, SLOT(on_currentChanged(QModelIndex,QModelIndex)));
void MainWindow::on_currentChanged(const QModelIndex ¤t, const QModelIndex &previous){Q_UNUSED(previous);if (!current.isValid()) return;labCellPos->setText(QString::asprintf("当前单元格: %d行,%d列", current.row(), current.column()));// 获取被选中的itemQStandardItem *item = theModel->itemFromIndex(current);labCellText->setText("单元内容:" + item->text());QFont font = item->font();ui->actFontBold->setChecked(font.bold());}
绑定数据与model:
content: 是一个二维的 QStringList,第一行是标题,每列之间是\t\t
测深(m) 总位移(m) 固井质量 测井取样252 0.51 优 1275 0.72 优 1325 1.09 良 1350 1.27 一般 0375 1.45 一般 0
void MainWindow::initModelFromStringList(QStringList &content){theModel->setRowCount(content.count() - 1); // 设置表有多少行// 设置表头QString header = content.at(0);QStringList headerList = header.split(QRegExp("\\s+"), QString::SkipEmptyParts);theModel->setHorizontalHeaderLabels(headerList);// 设置表格数据QStandardItem *item;for (int i=1; i<content.count(); i++) {QString lineText = content.at(i);QStringList itemList = lineText.split(QRegExp("\\s+"), QString::SkipEmptyParts);for (int j=0; j<itemList.count(); j++) {item = new QStandardItem(itemList.at(j));if (j == (FixedColumnCount-1)) {// 最后一列是checkboxitem->setText(headerList.at(j));item->setCheckable(true);if (itemList.at(j) == "1")item->setCheckState(Qt::Checked);elseitem->setCheckState(Qt::Unchecked);}theModel->setItem(i-1, j, item); // 因为去掉了表头,所以减1}}}
添加一行:
QList<QStandardItem *> itemList;QStandardItem *item;for (int i=0; i<FixedColumnCount; i++) {item = new QStandardItem();if (i == FixedColumnCount - 1) {item->setText(theModel->horizontalHeaderItem(i)->text());item->setCheckable(true);item->setCheckState(Qt::Checked);} elseitem->setText(QString::asprintf("new %d", i));itemList.append(item);}theModel->appendRow(itemList);// 设置选中的行theSelection->clearSelection();theSelection->setCurrentIndex(theModel->index(item->row(), 0), QItemSelectionModel::Select);
插入一行:
QModelIndex curIndex = theSelection->currentIndex();QStandardItem *curItem = theModel->itemFromIndex(curIndex);int curRow = curItem->row();QList<QStandardItem *> itemList;QStandardItem *item;for (int i=0; i<FixedColumnCount; i++) {item = new QStandardItem();if (i == FixedColumnCount - 1) {item->setText(theModel->horizontalHeaderItem(i)->text());item->setCheckable(true);item->setCheckState(Qt::Checked);} elseitem->setText(QString::asprintf("new %d", i));itemList.append(item);}theModel->insertRow(curRow, itemList);theSelection->clearSelection();theSelection->setCurrentIndex(theModel->index(item->row(), 0), QItemSelectionModel::Select);
删除一行:
QModelIndex curIndex = theSelection->currentIndex();theModel->removeRow(curIndex.row());// 最后一行不设置选中状态if (curIndex.row() < theModel->rowCount())theSelection->setCurrentIndex(curIndex, QItemSelectionModel::Select);
设置选中的item的字体样式:
if (!theSelection->hasSelection()) return;auto selectedIndexes = theSelection->selectedIndexes();for (int i=0; i<selectedIndexes.count(); i++) {auto index = selectedIndexes.at(i);QStandardItem *item = theModel->itemFromIndex(index);QFont font = item->font(); // 字体boldfont.setBold(checked);item->setFont(font);item->setTextAlignment(Qt::AlignLeft); // 左对齐}
