在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的客制化基本完成。

相关文章: