这里其实是用正则表达式检查文件/目录名的合法性. 这里面其实还是有几个比较有意思的地方
1. [^\/:*?"<>|]{1,255}这一串验证文件/目录名合法性的正则. 我正则不是专业的, 就正则30分钟入门那种水平, 这里的意思是排除\ / : * ? " < > | 这些特殊字符并且长度在1到255这个区间. 这里其实只能做一个简单的判断, 还有一些特别的限制没有考虑到, 比如文件名不能和设备名重名, 像Windows下你文件名就不能叫做COM1 COM2 这样的名字. 如果把所有因素都考虑在内的话, 这一串正则是及其复杂的.
2. 注意到没有[^\/:*?"<>|]{1,255}这串正则中并没有对应的转义字符, 并且被一个R"()"包裹着. 其实这是C++11的一个新特性, 原生字符串, 也是我很喜爱的一个特性, 在写正则的时候, 再也不必关心转义的问题了. 当然也可以像以前一样使用充满转义字符的正则表达式串. 人类在发展人类在进步啊啊啊啊
3. QRegExpValidator(rx/*, this*/);//bug
这一句我把this指针给注视掉了, 并且加了个//bug的注视, 原因是因为在QRegExpValidator的源码中有这么一个构造函数
explicit QRegExpValidator(const QRegExp& rx, QObject *parent = 0);
但是在Qt5.2 beta1中却始终编译不过. 隧把this指针给注视掉了.其他部分代码还是比较简单的.
//ProjectExplorerItemDelegate.h
#ifndef PROJECTEXPLORERITEMDELEGATE_H
#define PROJECTEXPLORERITEMDELEGATE_H
#include <QStyledItemDelegate>
/**
* @brief The ProjectExplorerItemDelegate class 项目浏览器的委托类
*/
class ProjectExplorerItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit ProjectExplorerItemDelegate(QObject *parent = 0);
//自定义委托需要重载的函数
/**
* @brief createEditor 返回一个组件,该组件会被作为用户编辑数据时所使用的编辑器,从模型中接受数据,返回用户修改的数据.
* @param parent 作为新的编辑器的父组件
* @param option 样式选项
* @param index 模型索引
* @return 自定义编辑器的指针
*/
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option,
const QModelIndex &index) const;
/**
* @brief setEditorData (从模型中获取需要编辑的数据)提供自定义编辑器在显示时候所需要的默认值(Qt::EditRole角色)
* @param editor 自定义编辑器的指针
* @param index 模型索引
*/
void setEditorData(QWidget *editor, const QModelIndex &index) const;
/**
* @brief setModelData 给Model设置用户修改后的新数据
* @param editor 自定义编辑器指针
* @param model 模型
* @param index 模型索引
*/
void setModelData(QWidget *editor, QAbstractItemModel *model,
const QModelIndex &index) const;
/**
* @brief updateEditorGeometry 确保自定义编辑器能够完整的显示
* @param editor 自定义编辑器指针
* @param option 单元格参数
* @param index 模型索引
*/
void updateEditorGeometry(QWidget *editor,
const QStyleOptionViewItem &option,
const QModelIndex &index) const;
};
#endif // PROJECTEXPLORERITEMDELEGATE_H
//ProjectExplorerItemDelegate.cpp
#include "ProjectExplorerItemDelegate.h"
#include <QDebug>
#include <QRegExp>
#include <QLineEdit>
#include <QRegExpValidator>
#include <QModelIndex>
#include <QVariant>
ProjectExplorerItemDelegate::ProjectExplorerItemDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *ProjectExplorerItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(option);
Q_UNUSED(index);
QLineEdit *pLineEdit = new QLineEdit(parent);
QRegExp rx(R"([^\/:*?"<>|]{1,255})");
QValidator *pValidator = new QRegExpValidator(rx/*, this*/);//bug
pLineEdit->setValidator(pValidator);
return pLineEdit;
}
void ProjectExplorerItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
QLineEdit *pLineEdit = static_cast<QLineEdit *>(editor);
//fileName or dirName
QString name = index.model()->data(index, Qt::EditRole).toString();
pLineEdit->setText(name);
}
void ProjectExplorerItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
QLineEdit *pLineEdit = static_cast<QLineEdit *>(editor);
QString name = pLineEdit->text();
model->setData(index, name, Qt::EditRole);
}
void ProjectExplorerItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
Q_UNUSED(index);
editor->setGeometry(option.rect);
}
注意直接复制粘贴以上代码在自己工程中, 并不能直接运行原因如下:
1. 这里没有给出几个menu的代码, 如果要在自己的工程中使用, 可以把涉及menu相关的代码注视掉.
2. 这里使用到了C++11的特性因此在项目配置文件(pro/pri)中加入对c++11的支持, pro/pri文件代码片段如下
greaterThan(QT_MAJOR_VERSION, 4){
CONFIG += c++11
}
equals(QT_MAJOR_VERSION, 4){
QMAKE_CXXFLAGS += -std=c++0x
}
如果是Qt5使用CONFIG += c++11加入对c++11的支持, 如果是Qt4则通过 QMAKE_CXXFLAGS += -std=c++0x 加入对C++11的支持.
在最后, 这并不是一个很完整很健壮的实现, 如果自己需要一个比较强大的ProjectExplorer, 推荐去阅读QtCreator的源码.