在QT编程中,客制化界面是一个很普遍的需求,毕竟QT在这方面确实很强大,作为常用的文件(夹)选择对话框,客制化在所难免。下面就详细介绍下,如何以最简单的方式客制化。
对于文件(夹)对话框的客制化,我采用的是将QFileDialog作为子控件嵌入到一个QDialog中的方式,这种方式下,不需要自己去实现复杂的控制、排序等逻辑,只要对嵌入的QFileDialog控件进行一些属性的设置,即可满足我们的基本需要。
下图为本人实现的效果图:
1、如何将QFileDialog嵌入QDialog中,请看如下代码:
QFileDialog* fileDlg = new QFileDialog;
fileDlg->setOption(QFileDialog::DontUseNativeDialog,true);
2、客制化QFileDialog中的子控件
相信大家采用上述方式嵌入后,会发现QFileDialog本身带的控件在显示方面还是不尽如人意,无法和我们的整体GUI风格进行匹配,那么下面介绍如何客制化QTreeView和QListView这两个显示文件(夹)的控件。直接上代码:
QTreeView* dlgTree = fileDlg->findChild<QTreeView*>();
if(dlgTree)
{
dlgTree->header()->setSectionResizeMode(0,QHeaderView::Stretch);
dlgTree->header()->setSectionResizeMode(2,QHeaderView::ResizeToContents);
dlgTree->header()->setSectionResizeMode(3,QHeaderView::ResizeToContents);
dlgTree->setFocusPolicy(Qt::NoFocus);
dlgTree->setEditTriggers(QAbstractItemView::NoEditTriggers);
dlgTree->setContextMenuPolicy(Qt::NoContextMenu);
}
QListView* listView = fileDlg->findChild<QListView*>();
if(listView)
{
listView->setFocusPolicy(Qt::NoFocus);
listView->setEditTriggers(QAbstractItemView::NoEditTriggers);
listView->setContextMenuPolicy(Qt::NoContextMenu);
}
QLineEdit* editFileName = fileDlg->findChild<QLineEdit*>();
if(editFileName)
{
editFileName->setText(strFile);
}
QTreeView就是DetailsView模式下,显示文件或者文件夹的容器控件,QListView则是ListView模式下,显示文件或者文件夹的容器控件。而QLineEdit则是选择文件时,显示选中文件名的控件
3.隐藏被过滤掉的文件(夹)
大家可以发现我的图片中,仅仅显示了一个文件,其它文件时隐藏的,那是如何实现的呢,采用代理!一般来说,当按照上述步骤完成,并设置了filter后,被过滤掉的项会以灰化的形式显示在界面上,这个很不美观,因此我们要想办法将其隐藏。通过度娘我找到了一个方法,那就是通过自定义一个继承自QSortFilterProxyModel的子类,并重写其filterAcceptRows方法,将不显示的项隐藏起来,下面为实现代码:
头文件:
#ifndef FILTERPROXYMODEL_H
#define FILTERPROXYMODEL_H
#include <QSortFilterProxyModel>
class FilterProxyModel : public QSortFilterProxyModel
{
Q_OBJECT
public:
protected:
virtual bool filterAcceptsRow(int source_row, const QModelIndex& source_parent) const override;
signals:
public slots:
};
#endif // FILTERPROXYMODEL_H
cpp文件:
#include "filterproxymodel.h"
#include <QFileSystemModel>
bool FilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
{
QModelIndex index0 = sourceModel()->index(sourceRow, 0, sourceParent);
QFileSystemModel* fileModel = qobject_cast<QFileSystemModel*>(sourceModel());
if (fileModel != NULL)
{
return fileModel->flags(index0) & Qt::ItemIsEnabled;
}
else
return false;
}
在客制化的filedialog中,对QFileDialog对象做如下设置:
FilterProxyModel* filterModel = new FilterProxyModel;
fileDlg->setProxyModel(filterModel);4.其它客制化项
4.1QFileDialog对话框右下角的sizeGrid
QFIleDialog被当做子控件嵌入后,右下角会有一个区域可拖动来改变对话框大小,这个也会影响我们的GUI美化,因此有必要隐藏它:
fileDlg->setSizeGripEnabled(false);
至此,QFileDialog的客制化基本完成。