正点原子QT之项目式视图组(基于模型)
9. 项目式视图组(基于模型)
(1) List View:清单视图
(2) Tree View:树形视图
(3) Table View:表视图
(4) Column View:列表视图
(5) Undo View:撤销列表视图9.1 QListView:清单视图
QListView 继承 QAbstractItemView,被 QListWidget 和 QUndoView 继承。 QListView 类提供模型上的列表或图标视图。 QListView 以简单的非分层列表或图标集合的形式显示存储在模型中的项。该类用于提供以前由 QListBox 和 QIconView 类提供的列表和图标视图,但是使用了 Qt 的模型/视图体系结构提供的更灵活的方法。案例:清单图
例 40_qlistview,清单图(难度:简单)。使用一个 ListView 控件,展示如何在列表中插入数据,其中表中的内容可编辑,可删除。
cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 设置主窗口位置与大小 */
this->setGeometry(0, 0, 800, 480);
/* 实例化 */
listView = new QListView(this);
/* 将listView居中 */
setCentralWidget(listView);
QStringList strList;
strList<<"高三(1)班"<<"高三(2)班"<<"高三(3)班";
/* 实例化,字符串模型 */
stringListModel = new QStringListModel(strList);
/* 向表中插入一段数据 */
listView->setModel(stringListModel);
/* 设置为视图为图标模式 */
listView->setViewMode(QListView::IconMode);
/* 设置为不可拖动 */
listView->setDragEnabled(false);
}
MainWindow::~MainWindow()
{
}9.2 QTreeView:树形视图
QTreeView 继承 QAbstractItemView,被 QTreeWidget 继承。 QTreeView 类提供树视图的默认模型/视图实现。 QTreeView 实现了模型项的树表示。该类用于提供以前由 QListView 类提供的标准分层列表,但是使用了 Qt 的模型/视图体系结构提供的更灵活的方法。案例:仿 word 标题
例 41_qtreeview,仿 word 标题(难度:简单)。要使一个 QTreeView 能够显示数据,需要构造一个 model 并设置 QTreeView。
cpp
#include "mainwindow.h"
#include <QStandardItemModel>
#include <QStandardItem>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 设置窗口的位置与大小 */
this->setGeometry(0, 0, 800, 480);
/* 实例化QTreeView对象 */
treeView = new QTreeView(this);
/* 居中 */
setCentralWidget(treeView);
/* 构建Model */
QStandardItemModel *sdiModel = new QStandardItemModel(treeView);
sdiModel->setHorizontalHeaderLabels(
QStringList()<<QStringLiteral("标题")
<< QStringLiteral("名称")
);
for(int i = 0; i < 5; i++) {
/* 一级标题 */
QList<QStandardItem*> items1;
QStandardItem* item1 =
new QStandardItem(QString::number(i));
QStandardItem* item2 =
new QStandardItem(QStringLiteral("一级标题"));
/* 添加项一 */
items1.append(item1);
/* 添加项二 */
items1.append(item2);
/* appendRow方法添加到model上 */
sdiModel->appendRow(items1);
for(int j = 0; j < 5; j++) {
/* 在一级标题后面插入二级标题 */
QList<QStandardItem*> items2;
QStandardItem* item3 =
new QStandardItem(QString::number(j));
QStandardItem* item4 =
new QStandardItem(QStringLiteral("二级标题"));
items2.append(item3);
items2.append(item4);
/* 使用appendRow方法添加到item1上 */
item1->appendRow(items2);
}
}
/* 设置Model给treeView */
treeView->setModel(sdiModel);
}
MainWindow::~MainWindow()
{
}9.3 QTableView:表视图
QTableView 继承 QAbstractItemView,被 QTableWidget 继承。 QTableView 类提供了表视图的默认模型/视图实现。 QTableView 实现了一个表视图,用于显示来自模型的项。该类用于提供以前由 QTable 类提供的标准表,但使用 Qt 的模型/视图体系结构提供的更灵活的方法。案例:表格视图
例 42_qtableview,表格视图(难度:简单)。要使一个 QTableView 能够显示数据,需要构造一个 model 并设置给 QTableView。
cpp
#include "mainwindow.h"
#include <QStandardItemModel>
#include <QHeaderView>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 设置窗口的位置与大小 */
this->setGeometry(0, 0, 800, 480);
tableView = new QTableView(this);
setCentralWidget(tableView);
/* 显示网格线 */
tableView->setShowGrid(true);
QStandardItemModel* model = new QStandardItemModel();
QStringList labels =
QObject::tr("语文,数学,英语").simplified().split(",");
/* 设置水平头标签 */
model->setHorizontalHeaderLabels(labels);
/* item */
QStandardItem* item = 0;
/* model插入项内容 */
for(int i = 0; i < 5; i++){
item = new QStandardItem("80");
model->setItem(i, 0, item);
item = new QStandardItem("99");
model->setItem(i, 1, item);
item = new QStandardItem("100");
model->setItem(i, 2, item);
}
/* 将model设置给tableView */
tableView->setModel(model);
/* 平均分列 */
tableView->horizontalHeader()
->setSectionResizeMode(QHeaderView::Stretch);
/* 平均分行 */
tableView->verticalHeader()
->setSectionResizeMode(QHeaderView::Stretch);
}
MainWindow::~MainWindow()
{
}9.4 QColumnView:列表视图
ColumnView 继承 QAbstractItemView。QColumnView 在许多 QListViews 中显示一个模型,每个 QListViews 对应树中的每个层次结构。这有时被称为级联列表。 QColumnView 类是模型/视图类之一,是 Qt 模型/视图框架的一部分。案例:收货地址
例 43_qcolumnview,收货地址(难度:简单)。使用一个 QColumnView,向其插入多级QStandardItem。这样就可以模拟成一个多级联的视图。与我们在像某宝,某东里填写的收货地址十分类似。
cpp
#include "mainwindow.h"
#include <QStandardItem>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 设置主窗体显示位置与大小 */
this->setGeometry(0, 0, 800, 480);
QStandardItemModel *model = new QStandardItemModel;
/* 省份 */
QStandardItem *province = new QStandardItem("广东省");
/* 城市 */
QStandardItem *city1 = new QStandardItem("茂名市");
QStandardItem *city2 = new QStandardItem("中山市");
/* 添加城市到省份下 */
province->appendRow(city1);
province->appendRow(city2);
QStandardItem *town1 = new QStandardItem("电白镇");
QStandardItem *town2 = new QStandardItem("南头镇");
/* 添加城镇到城市下 */
city1->appendRow(town1);
city2->appendRow(town2);
columnView = new QColumnView;
/* 建立model */
model->appendRow(province);
/* 设置model */
columnView->setModel(model);
/* 设置居中 */
setCentralWidget(columnView);
}
MainWindow::~MainWindow()
{
}9.5 QUndoView:撤销列表视图
QUndoView 继承 QlistView。 QUndoView 类显示 QUndoStack 的内容。 QUndoView 是一个QListView,它显示在撤销堆栈上推送的命令列表。总是选择最近执行的命令。案例:仿 PS 历史记录
例 44_qundoview,仿 PS 历史记录(难度:一般)。如果大家学习过 PS,都知道 PS 里有个历史记录面板,点击就会撤回到历史记录的步骤。
cpp
#include "mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
/* 设置主窗体显示的位置与大小 */
this->setGeometry(0, 0, 800, 480);
/* 实例一个水平布局,用于左侧按钮区域与右侧历史记录面板 */
hLayout = new QHBoxLayout();
/* 实例一个水平布局,用于左侧标签与按钮 */
vLayout = new QVBoxLayout();
/* 主Widget, 因为MainWindow自带一个布局,
* 我们要新建一个Widget容纳新布局
*/
mainWidget = new QWidget();
/* 用于存放命令行栈 */
undoStack = new QUndoStack(this);
/* 用于容纳左侧标签与按钮布局 */
widget = new QWidget();
/* 历史记录面板实例化 */
undoView = new QUndoView(undoStack);
/* 实例化一个按钮,用于加一操作 */
pushButton = new QPushButton();
/* 标签,用于显示计算结果 */
label = new QLabel();
/* 设置widget的大小 */
widget->setMinimumSize(400, 480);
/* 将两个widget添加到水平布局 */
hLayout->addWidget(widget);
hLayout->addWidget(undoView);
/* 初始化count的值 */
count = 0;
/* 显示初始化计算结果 */
label->setText("计算结果:" + QString::number(count));
label->setAlignment(Qt::AlignCenter);
/* 左侧布局 */
vLayout->addWidget(label);
vLayout->addWidget(pushButton);
/* 左侧布局控件的高度设置 */
label->setMaximumHeight(this->height() / 5);
pushButton->setMaximumHeight(this->height() / 5);
/* 按钮文件设置 */
pushButton->setText("加1");
/* 设置widget的布局为vLayout */
widget->setLayout(vLayout);
/* 将主窗体的布局设置为hLayout */
mainWidget->setLayout(hLayout);
/* 设置mainWidget为主窗体的居中widget */
this->setCentralWidget(mainWidget);
/* 信号槽连接,按钮点击,执行加一操作 */
connect(pushButton, SIGNAL(clicked()), this,
SLOT(pushButtonClieked()));
/* 信号槽连接,历史记录项index发生变化,显示count大小 */
connect(undoStack, SIGNAL(indexChanged(int) ),
this, SLOT(showCountValue(int)));
}
/* 入栈操作会自动调用addCommand的redo */
void MainWindow::pushButtonClieked()
{
/* 变量值加一 */
count++;
/* value指向count的地址 */
int *value = &count;
/* 用重写的addCommand类实例化 */
QUndoCommand *add = new addCommand(value);
/* 入栈 */
undoStack->push(add);
}
void MainWindow::showCountValue(int)
{
/* 标签用于显示计算结果 */
label->setText("计算结果:" + QString::number(count));
}
MainWindow::~MainWindow()
{
}cpp
#include "command.h"
#include <QDebug>
addCommand::addCommand(int *value, QUndoCommand *parent)
{
/* 使用Q_UNUSED,避免未使用的数据类型 */
Q_UNUSED(parent);
/* undoView显示的操作信息 */
setText("进行了加1操作");
/* value的地址赋值给new_count */
new_count = value;
/* 让构造函数传过来的*new_count的值赋值给old_count */
old_count = *new_count;
}
/* 执行stack push时或者重做操作时会自动调用 */
void addCommand::redo()
{
/* 重新赋值给new_count */
*new_count = old_count;
/* 打印出*new_count的值 */
qDebug()<<"redo:"<<*new_count<<endl;
}
/* 回撤操作时执行 */
void addCommand::undo()
{
/* 回撤操作每次应减一 */
(*new_count)--;
/* 打印出*new_count的值 */
qDebug()<<"undo:"<<*new_count<<endl;
}
addCommand::~addCommand()
{
}
阿源的知识库