基于Qt/C++的ProjectExplorer实现(3)

这里其实是用正则表达式检查文件/目录名的合法性. 这里面其实还是有几个比较有意思的地方

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的源码.

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/5caba20ec6f3ceed823038ed8f512224.html