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(); // 获取最后一项的row
theModel->insertRow(lastRow); // 在最后一项添加一个新item
QModelIndex idx = theModel->index(lastRow, 0); // 获取这个row的index
theModel->setData(idx, "new item", Qt::DisplayRole); // 设置值
ui->listView->setCurrentIndex(idx); // 设置最后一项被选中
在被选中的地方插入新item:
// 先在model中增加一个item
QModelIndex index = ui->listView->currentIndex(); // 获取被选择中的row的index
theModel->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列的model
theSelection = new QItemSelectionModel(theModel); // 绑定select到model
ui->tableView->setModel(theModel); // 绑定view
ui->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()));
// 获取被选中的item
QStandardItem *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 优 1
275 0.72 优 1
325 1.09 良 1
350 1.27 一般 0
375 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)) {
// 最后一列是checkbox
item->setText(headerList.at(j));
item->setCheckable(true);
if (itemList.at(j) == "1")
item->setCheckState(Qt::Checked);
else
item->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);
} else
item->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);
} else
item->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(); // 字体bold
font.setBold(checked);
item->setFont(font);
item->setTextAlignment(Qt::AlignLeft); // 左对齐
}