十、项目视图ItemViews
10.1 清单视图QListView
QListView 将存储在模型中的项呈现为简单非分层列表或图标的集合。此类用于提供列表和图标视图,以前提供通过 and 类,但使用由 Qt 模型/视图体系结构提供的方式更灵活。
QListView 类是一种模型/视图类 且属于 Qt 的 模型/视图框架 .
此视图不显示水平或垂直标题;要显示具有水平标题的项列表,使用 QTreeView 代替。
QListView 实现接口的定义通过 QAbstractItemView 类以允许它显示提供数据,通过模型派生自 QAbstractItemModel 类。
可以使用 2 种视图模式之一显示列表视图中的项:按 ListMode ,项目以简单列表形式显示;按 IconMode ,列表视图接受的形式为 图标视图 其中项按 图标 显示 (像:文件管理器中的文件)。默认情况下,列表视图按 ListMode 。要改变视图模式,使用 setViewMode () 函数,和要确定当前视图模式,使用 viewMode ().
这些视图项的布置方向指定通过 flow () 对于列表视图。项可能固定在到位,或允许移动,从属视图 movement () 状态。
若模型中的项无法完全按流方向布置,可以在视图 Widget 边界处换行它们;这取决于 isWrapping ()。此特性很有用,当按图标视图表示项时。
resizeMode () 和 layoutMode () 支配项的布局方式和时间。项间隔按照其 spacing (),且可以存在于名义大小栅格中指定通过 gridSize ()。项可以渲染为大图标 (或小图标) 从属其 iconSize ().
我们先创建QWidget工程。
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<QListView>
#include<QMessageBox>
#include<QStringListModel>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
QListView *lv;
private slots:
void clickedfunc(const QModelIndex &index);
};
#endif // WIDGET_H
QModelIndex类用于定位数据模型中的数据。
widget.cpp
先实例化QListView对象并且设置位置大小。
lv=new QListView(this);
lv->setGeometry(20,20,240,160);
创建一些数据给清单视图。
QStringList sl;
sl.append("运动类:篮球、足球");
sl.append("娱乐类:看电影、写小说、听音乐");
sl.append("游戏类:五子棋、扑克牌、中国象棋");
sl.append("旅游类:国外旅游、国内旅游");
QStringListModel *slm=new QStringListModel(sl);
lv->setModel(slm);
QStringListModel类是字符串列表模型。
实现槽函数。
connect(lv,SIGNAL(clicked(const QModelIndex)),this,SLOT(clickedfunc(const QModelIndex)));
void Widget::clickedfunc(const QModelIndex &index)
{
QMessageBox::information(NULL,"兴趣爱好","你选择的类型为:\n"+index.data().toString());
}
前面说过QModelIndex是用于定位数据模型里的数据的,当点击数据时,就会发出信号,并把数据传入到槽函数,然后槽函数通过index.data()找到数据并把数据转换成字符串类型显示在消息对话框中。
对于QMessageBox::information函数请看这里。
完整代码
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
resize(450,250);
lv=new QListView(this);
lv->setGeometry(20,20,240,160);
QStringList sl;
sl.append("运动类:篮球、足球");
sl.append("娱乐类:看电影、写小说、听音乐");
sl.append("游戏类:五子棋、扑克牌、中国象棋");
sl.append("旅游类:国外旅游、国内旅游");
QStringListModel *slm=new QStringListModel(sl);
lv->setModel(slm);
connect(lv,SIGNAL(clicked(const QModelIndex)),this,SLOT(clickedfunc(const QModelIndex)));
}
Widget::~Widget()
{
delete ui;
}
void Widget::clickedfunc(const QModelIndex &index)
{
QMessageBox::information(NULL,"兴趣爱好","你选择的类型为:\n"+index.data().toString());
}
10.2 树视图QTreeView
QTreeView 实现模型项的树表示。此类用于提供标准分层列表,先前提供通过 类,但使用由 Qt 模型/视图体系结构提供的方式更灵活。
QTreeView 类是一种 模型/视图类 且属于 Qt 的 模型/视图框架 .
QTreeView 实现的接口定义通过 QAbstractItemView 类以允许它显示提供数据,通过模型派生自 QAbstractItemModel 类。
我们创建一个QMainWindow工程。
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include<QStandardItemModel>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
QStandardItemModel *sim;
};
#endif // MAINWINDOW_H
QStandardItemModel:基于项数据的标准数据模型,可以处理二维数据。维护一个二维的项数据数组,每个项是一个 QStandardltem 类的变量,用于存储项的数据、字体格式、对齐方式等。
接下来我们把QTreeView放到QStandardItemModel里面,实现树形图。
首先设置一下mainwindow.ui文件。
我们加入一个TreeView工具框。
第一步,构造Model。
sim=new QStandardItemModel(ui->treeView);
sim->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("编号")<<QStringLiteral("初中部|高中部"));
首先看一下QStandardItemModel的构造函数。
void QStandardItemModel:: setVerticalHeaderLabels (const QStringList & labels ):
使用 labels 设置垂直标题标签。如有必要,行数将增加到标签 的大小。
QStringLiteral(str):
使用 QStringLiteral 宏可以在编译期把代码里的常量字符串 str 直接构造为 QString 对象,于是运行时就不再需要额外的构造开销了。
如果编译器支持,则 QStringLiteral 宏在编译时从 str 生成一个 QString 的数据。在这种情况下从 QStringLiteral 创建一个 QString 是自由的,生成的字符串数据存储在编译的目标文件的只读段中。
对于不支持创建编译时字符串的编译器,QStringLiteral 的使用效果将与使用 QString::fromUtf8() 一样。
创建一级节点,值得注意的是,由于QStandardItemModel里的数据都是QStandardItem数据,所以我们在为节点加入到模块时应该把数据类型变成QStandardItem才行。
//创建一级节点
QList<QStandardItem*> item1;
QStandardItem *item11=new QStandardItem(QString::number(1));
QStandardItem *item12=new QStandardItem("初中部");
item1.append(item11);
item1.append(item12);
sim->appendRow(item1);
//应用到QTreeView
ui->treeView->setModel(sim);
Item1之所以需要创建QList对象,是因为appendRow函数的参数是QList类型。
void QStandardItemModel::appendRow(const QList<QStandardItem *> &items):
追加包含项的行。如有必要,将列计数增加到项的大小。
创建二级节点。
//创建二级节点
QList<QStandardItem*> item2;
QStandardItem *item21=new QStandardItem(QString::number(2));
QStandardItem *item22=new QStandardItem("一年级");
item2.append(item21);
item2.append(item22);
item11->appendRow(item2);
//应用到QTreeView
ui->treeView->setModel(sim);
因为二级节点是在一级节点后面,所以应该把整个二级节点行添加到一级节点里,如果再有三级节点、四级节点...等等,依次类推。
完整代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//构造Model
sim=new QStandardItemModel(ui->treeView);
sim->setHorizontalHeaderLabels(QStringList()<<QStringLiteral("编号")<<QStringLiteral("初中部|高中部"));
//创建一级节点
QList<QStandardItem*> item1;
QStandardItem *item11=new QStandardItem(QString::number(1));
QStandardItem *item12=new QStandardItem("初中部");
item1.append(item11);
item1.append(item12);
sim->appendRow(item1);
//创建二级节点
QList<QStandardItem*> item2;
QStandardItem *item21=new QStandardItem(QString::number(2));
QStandardItem *item22=new QStandardItem("一年级");
item2.append(item21);
item2.append(item22);
item11->appendRow(item2);
//应用到QTreeView
ui->treeView->setModel(sim);
}
MainWindow::~MainWindow()
{
delete ui;
}
10.3表视图QTableView
QTableView 实现从模型显示项的表格视图。此类用于提供先前由 QTable 类提供的标准表格,但使用由 Qt 模型/视图体系结构提供的更灵活方式。
QTableView 类是一种 模型/视图类 且属于 Qt 的 模型/视图框架 .
QTableView 实现的接口定义通过 QAbstractItemView 类以允许它显示提供数据,通过模型派生自 QAbstractItemModel 类。
我们创建QMainWindow工程。这次只在mainwindow.cpp文件写代码。
mainwindow.ui
我们继续使用QStandardItemModel类来实现QTableView。
还是一样,要想使用QStandardItemModel类,必须加入QStandardItem类的数据,创建对象后,在加入到QTableView中。
QStandardItemModel *sim=new QStandardItemModel(ui->tableView);
sim->setHorizontalHeaderItem(0,new QStandardItem(QObject::tr("学号")));
sim->setHorizontalHeaderItem(1,new QStandardItem(QObject::tr("姓名")));
sim->setHorizontalHeaderItem(2,new QStandardItem(QObject::tr("性别")));
ui->tableView->setModel(sim);
//设置列表的宽度
ui->tableView->setColumnWidth(0,120);
void QStandardItemModel:: setHorizontalHeaderItem ( int column(列) , QStandardItem * item ):
将列的水平标题项设置为项 。模型获取项目的所有权。如有必要,将增加列数以适合项目。删除以前的标题项(如果有)。
void QTableView:: setColumnWidth ( int column(列) , int width(宽度) ):
设置宽度为给定 column 到 width 。
添加数据
sim->setItem(0,0,new QStandardItem("415155"));
sim->setItem(0,1,new QStandardItem("张三"));
sim->setItem(0,2,new QStandardItem("男"));
sim->setItem(1,0,new QStandardItem("352626"));
sim->setItem(1,1,new QStandardItem("李四"));
sim->setItem(1,2,new QStandardItem("女"));
//禁止编辑
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
//排序
sim->sort(3,Qt::DescendingOrder);
void QStandardItemModel:: setItem ( int row (行), int column(列) , QStandardItem * item ):
将给定行和列的项设置为 项 。模型获取项目的所有权。如有必要,将增加行数和列数以适合项目。给定位置的上一项(如果有)将被删除。
void setEditTriggers(QAbstractItemView::EditTriggers triggers(触发器)):
此属性保存将启动项编辑的操作
此属性是EditTrigger定义的标志选择,使用OR操作符组合。只有在此属性中设置了执行的操作时,视图才会启动对项目的编辑。
void QStandardItemModel:: sort ( int column(列) , Qt::SortOrder order = Qt::AscendingOrder(升序)) :
按列 对模型进行排序 以给定 order .
完整代码
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QStandardItemModel>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QStandardItemModel *sim=new QStandardItemModel(ui->tableView);
sim->setHorizontalHeaderItem(0,new QStandardItem(QObject::tr("学号")));
sim->setHorizontalHeaderItem(1,new QStandardItem(QObject::tr("姓名")));
sim->setHorizontalHeaderItem(2,new QStandardItem(QObject::tr("性别")));
ui->tableView->setModel(sim);
//设置列表的宽度
ui->tableView->setColumnWidth(0,120);
sim->setItem(0,0,new QStandardItem("415155"));
sim->setItem(0,1,new QStandardItem("张三"));
sim->setItem(0,2,new QStandardItem("男"));
sim->setItem(1,0,new QStandardItem("352626"));
sim->setItem(1,1,new QStandardItem("李四"));
sim->setItem(1,2,new QStandardItem("女"));
//禁止编辑
ui->tableView->setEditTriggers(QAbstractItemView::NoEditTriggers);
//排序
sim->sort(3,Qt::DescendingOrder);
}
MainWindow::~MainWindow()
{
delete ui;
}