在项目中,针对一个数据模型,可能会有不同的展示需求,或以表格列表形式展示,或以树,复杂点可能是各种统计图,在接下来的文章中,小豆君就为大家介绍下Qt中的各种视图控件的使用方法。
在Qt中,提供了最基本的三种视图控件,分别是列表视图、表格视图和树视图。
这篇文章就先来给大家介绍下列表视图,所谓列表,大家都很熟悉了,在我们生活中也经常看到,比如QQ微信的好友列表,公众号的文章列表等等,在Qt中列表视图使用QListView类来表示。
1 QListView属性介绍
老规矩,查看一个类,最好的方法就是先看它有哪些属性:
下面对其每个属性做一介绍
batchSize和layoutMode一起介绍
1.1 flow
在列表控件中的每个item,其实都是存在于布局之中的,flow字面意思是流动的意思,既然流动就会有一个方向。
LeftToRight 代表从左到右排列item,如果isWrapping为true,在item到达可见区域的最右边时会自动换行。
TopToBottom 代表从上到下排列item,如果isWrapping为true,在item到达可见区域的最下边时会自动换行。
1.2 gridSize
对于每个item其大小不一定完全一样,如果把每个item排列起来,对于多行item,那么他们很可能不会对齐,这对有强迫症的人来说是很不舒服的,为此,为了使item可以彼此对齐,可以设置每个item的网格大小。默认情况下是不存在网格的。 注意,这里并不是指item的大小,而是网格的大小,item被放置在网格内。
1.3 isWrapping
当item到达可见区域边缘时是否自动换行。
1.4 layoutMode和batchSize
当设置view中的item自动换行,或者当view大小改变后item需自动调整位置时,可以设置layoutMode属性,从而决定让全部item一次性调整位置还是item成批次调整位置。
SinglePass 全部item一次性重新布局
Batched item按批次重新布局,每批次为batchSize个item。
1.5 modelColumn
我们知道,在一个model模型中可以存放多列数据,但是QListView只能显示一列数据,在默认情况下,QListView显示第一列数据,如果指定modelColumn设为n,view将显示model的第n列数据。
1.6 movement
前面我们讲了,QListView是可以有网格的,如果我想移动item(可类比电脑桌面上的图标),则可以选择移动方式,自由移动,或按网格移动,或根本不能移动。
Static 不能移动item 此为默认
Free 可自由移动item
Snap 只能在网格间移动
1.7 resizeMode
当为true时,表示如果view窗口大小改变,item会重新布局。
1.8 selectionRectVisible
当我们在多选item时,往往希望能有一个矩形框来帮助我们选择多个item,如果设置该属性为true,则可按住鼠标框选多个item
1.9 spacing
很简单,就是item之间的间距
1.10 uniformItemSizes
当视图中的每个item具有相同大小时,可以设置该属性为true,这会让视图进行一些性能优化。对于显示大量大小相同的item时,这是一个提升性能的很好的办法。
1.11 viewMode
视图模式,该属性可以让item以列表或图标模式显示,可以类比于windows窗口的列表模式和缩略图模式。
ListMode item以列表方式显示
IconMode item以图标方式显示
1.12 wordWrap
item是否换行
下面我们就以实际的示例来看看这些属性的用法吧
2 示例
该示例可以以缩略图的形式显示一个文件夹下的所有图片。
新建一个ui application工程ListWidget,类名为ListWidget,继承自QWidget,不需要生成ui。
listwidget.h
#ifndef LISTWIDGET_H #define LISTWIDGET_H #include <QWidget> #include <QStandardItemModel> #include <QFileInfoList> #include <QListView> class ListWidget : public QWidget { Q_OBJECT public: ListWidget(QWidget *parent = 0); ~ListWidget(); //设置图片文件夹,显示该文件夹下的所有图片 void setDir(const QString& dirPath); //清空显示 void clear(); private: //初始化所有控件 void initControl(); //初始化所有右键命令,所有命令均来自于view的属性 void initActions(); //重新设置模型数据 infos所有图片文件信息列表 void resetModel(const QFileInfoList &infos); //重新设置view void resetView(); //获取指定路径下的图片文件信息列表 QFileInfoList getImageFileInfoList(const QString &dirPath) const; //添加QListView的各个属性动作 void addActionFlow(); void addActionWrapping(); void addActionMoveMent(); void addActionResizeMode(); void addActionViewMode(); //将动作添加到右键菜单,并按动作组进行管理 void setActions(const QList<QAction*>& actions); private: QStandardItemModel* model; QListView* view; QMenu* menu; }; #endif // LISTWIDGET_H
listwidget.cpp
#include <QMenu> #include <QAction> #include <QListWidget> #include <QDebug> #include <QDir> #include <QVBoxLayout> #include "listwidget.h" ListWidget::ListWidget(QWidget *parent) : QWidget(parent) { initControl(); initActions(); resetView(); setDir("F:/Picture/Qt/"); } ListWidget::~ListWidget() { } //设置图片文件夹,显示该文件夹下的所有图片 void ListWidget::setDir(const QString &dirPath) { clear(); resetModel(getImageFileInfoList(dirPath)); } //清空显示 void ListWidget::clear() { model->clear(); } //初始化所有控件 void ListWidget::initControl() { /*创建模型*/ model = new QStandardItemModel; /*创建view,并对view进行设置*/ view = new QListView; view->setModel(model); view->setSelectionRectVisible(true);//设置框选矩形框可见 //设置选择模式,该模式为最常用模式,其他选择模式请自行查看帮助说明 //按住ctrl可多选,按住shift可连续多选 //当点击另一个item,其他被选中的item会取消选中状态 view->setSelectionMode(QAbstractItemView::ExtendedSelection); QVBoxLayout* layout = new QVBoxLayout(this); layout->addWidget(view); //设置右键菜单为自定义菜单,关于菜单模式以后会讲到 menu = new QMenu(this); setContextMenuPolicy(Qt::CustomContextMenu); connect(this, &QWidget::customContextMenuRequested, [=](const QPoint &pos) { menu->exec(mapToGlobal(pos)); }); } //初始化所有右键命令,所有命令均来自于view的属性 void ListWidget::initActions() { addActionFlow(); menu->addSeparator(); addActionWrapping(); menu->addSeparator(); addActionMoveMent(); menu->addSeparator(); addActionResizeMode(); menu->addSeparator(); addActionViewMode(); } //重新设置模型数据 infos所有图片文件信息列表 void ListWidget::resetModel(const QFileInfoList &infos) { for(auto &&info : infos) { //定义QStandardItem对象 QStandardItem *imageItem = new QStandardItem; //为单元项设置属性 imageItem->setIcon(QIcon(info.absoluteFilePath())); imageItem->setText(info.fileName()); model->appendRow(imageItem); } } //重新设置view void ListWidget::resetView() { //设置QStandardItem中单元项的图片大小 view->setIconSize(QSize(100,100)); //设置QStandardItem中单元项的间距 view->setSpacing(10); } //获取指定路径下的图片文件信息列表 QFileInfoList ListWidget::getImageFileInfoList(const QString& dirPath) const { QDir dir(dirPath); QStringList filters; filters <<"*.png" << "*.bmp" << "*.jpg" << "jpeg"; return dir.entryInfoList(filters, QDir::Files, QDir::Name); } //添加QListView的各个属性动作 void ListWidget::addActionFlow() { QAction* actLeftToRight = new QAction("LeftToRight"); connect(actLeftToRight, &QAction::triggered, [=](bool) { view->setFlow(QListView::LeftToRight); }); QAction* actTopToBottom = new QAction("TopToBottom"); actTopToBottom->setChecked(true); connect(actTopToBottom, &QAction::triggered, [=](bool) { view->setFlow(QListView::TopToBottom); }); QList<QAction*> actions; actions << actLeftToRight << actTopToBottom; setActions(actions); actTopToBottom->setChecked(true); } void ListWidget::addActionWrapping() { QAction* actWrapping = new QAction("Wrapping"); connect(actWrapping, &QAction::toggled, [=](bool b) { view->setWrapping(b); }); QList<QAction*> actions; actions << actWrapping; setActions(actions); } void ListWidget::addActionMoveMent() { QAction* actStatic = new QAction("Static"); connect(actStatic, &QAction::triggered, [=](bool) { view->setMovement(QListView::Static); }); QAction* actFree = new QAction("Free"); connect(actFree, &QAction::triggered, [=](bool) { view->setMovement(QListView::Free); }); QAction* actSnap = new QAction("Snap"); connect(actSnap, &QAction::triggered, [=](bool) { view->setMovement(QListView::Snap); }); QList<QAction*> actions; actions << actStatic << actFree << actSnap; setActions(actions); actStatic->setChecked(true); } void ListWidget::addActionResizeMode() { QAction* actFixed = new QAction("Fixed"); connect(actFixed, &QAction::triggered, [=](bool) { view->setResizeMode(QListView::Fixed); }); QAction* actAdjust = new QAction("Adjust"); connect(actAdjust, &QAction::triggered, [=](bool) { view->setResizeMode(QListView::Adjust); }); QList<QAction*> actions; actions << actFixed << actAdjust; setActions(actions); actFixed->setChecked(true); } void ListWidget::addActionViewMode() { QAction* actListMode = new QAction("ListMode"); connect(actListMode, &QAction::triggered, [=](bool) { view->setViewMode(QListView::ListMode); }); QAction* actIconMode = new QAction("IconMode"); connect(actIconMode, &QAction::triggered, [=](bool) { view->setViewMode(QListView::IconMode); }); QList<QAction*> actions; actions << actListMode << actIconMode; setActions(actions); actListMode->setChecked(true); } //将动作添加到右键菜单,并按动作组进行管理 void ListWidget::setActions(const QList<QAction *> &actions) { QActionGroup* group = new QActionGroup(this); for(auto a: actions) { a->setCheckable(true); group->addAction(a); menu->addAction(a); } }
运行程序 按如下选择右键菜单
好了,关于QListView的介绍就到这里啦,利用它可以实现简单的文件系统查看器,如果您觉得有用,就给小豆君点个赞吧!
最后也希望大家多多支持小豆君的创作,关注小豆君的公众号“小豆君Qt分享”,最新文章都会在公众号第一时间发布,或者你有不懂的问题,关注公众号后,可加好友或进Qt群获得答案。