在項目中,針對一個數據模型,可能會有不同的展示需求,或以表格列表形式展示,或以樹,複雜點可能是各種統計圖,在接下來的文章中,小豆君就為大家介紹下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群獲得答案。

推薦閱讀:

相关文章