Qt:文件浏览器添加右击菜单实现重命名

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cfqcfqcfqcfqcfq/article/details/51245746

     功能内容:

    1、实现右击菜单(重点:如何只在Item项上面弹出右击菜单,而在空白处不弹出菜单)

    2、实现重命名功能

    3、使用使用委托类实现对重命名检查,后缀名更改时给予警告

最后在编译程序时出现了2个编译错误(检查老半天才把问题纠察出来)。把相关错误写出来,给以后做参考!


1 实现右击菜单

    网上有很多资料讲解了右击菜单的实现。但大多数都是基于QListWidget视图,本人实现的浏览器是QtreeView视图,所以相对来说有部分不同。但都是大同小异。

 实现右键菜单, 必须重写下面这个函数

void QWidget::contextMenuEvent ( QContextMenuEvent * event )   [virtual protected]
  这个函数是QWidget的一个虚函数,使用时必须由QWidget的子类重写该函数。

本文中该函数的重新如下:

//实现右击菜单
void fileView::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu* popMenu = new QMenu(this);
QModelIndex currIndex=this->tree->indexAt(tree->viewport()->mapFromGlobal(event->globalPos()));
 int i=currIndex.row();
    // qDebug()<<"right:"<<i;
   if(i!=-1)
   {
     QAction *Rename=new QAction(QObject::tr("Rename"),this);
     popMenu->addAction(Rename);
     connect(Rename,SIGNAL(triggered(bool)),this,SLOT(slotRename()));
   }
   popMenu->exec( QCursor::pos() );
}
说明:该函数实现与参考文献1中最大的差别就是关于通过鼠标位置确定来获取当前所对应的项。在QtreeView中没有ItemAt(widget_pos)函数,取而代之的是indexAt(viewport_pos)函数 该函数返回当前的模式索引QModelIndex.括号里的坐标参数也不一样 indexAt参数为视口坐标参数  Qt文档中indexAt()解释:

QModelIndex QAbstractItemView::indexAt(const QPoint & point) const
Returns the model index of the item at the viewport coordinates point.
In the base class this is a pure virtual function.

2重命名的实现

  最简单的实现就是使用edit() 函数 所有的视图类都有该函数。但是本文在使用时候发现一直提示:editing fail. 

经过查看Qt文档发现是由于使用的模型的原因。Qtreeview所对应的模型是:QFileSystemModel 在文档中有这样的描述:

This class provides access to the local filesystem, providing functions for renaming and removing files and directories, and for creating new directories
 可见该类是支持重命名的,但为何在程序中不能实现呢 又看到有一个属性 readOnly 描述如下:

readOnly : bool
This property holds whether the directory model allows writing to the file system.
If this property is set to false, the directory model will allow renaming, copying and deleting of files and directories.
This property is true by default
Access functions:

bool	isReadOnly() const
void	setReadOnly(bool enable)

  原来默认情况下是只读的!所以可以通过setReadOnly(false)设置为可编辑的

3、委托机制

  上一节的重命名只是简单的文本编辑功能,不能够进行编辑结果的检查,这时候使用委托机制,可以很好的完成相应的工作

    关于委托参见参考文献2.实现一个委托类 要继承QStyledItemDelegate. 并且重新实现一下四个类:

   createEditor():返回一个组件。该组件会被作为用户编辑数据时所使用的编辑器,从模型中接受数据,返回用户修改的数据。
    setEditorData():提供上述组件在显示时所需要的默认值。
      updateEditorGeometry():确保上述组件作为编辑器时能够完整地显示出来。
    setModelData():返回给模型用户修改过的数据。

后缀名检查机制是通过在编辑前和编辑完成之后通过FileInfo类获取文件的后缀名。如果后缀名不相同则说明后缀名发生了更改。给予对应的警告。在setEditorData中获取编辑前后缀名  在setModelData获取修改后的文件后缀名 比与之前后缀名进行比较判断

//从模型中获取编辑数据
void TextBoxDelegate::setEditorData(QWidget *editor, const QModelIndex &index)const
{
    QString value=index.model()->data(index,Qt::EditRole).toString();
    QLineEdit *TextBox=static_cast<QLineEdit*>(editor);
    TextBox->setText(value);

    //获取文件后缀名
    QFileInfo tmpInfo(value);
    startExt=tmpInfo.suffix();
   // qDebug()<<startExt;
}

//保存数据到模型
void TextBoxDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,
                                   const QModelIndex &index) const
{
       QLineEdit *TextBox=static_cast<QLineEdit*>(editor);
       QString value=TextBox->text();
       //获取后缀名
       QFileInfo tmpInfo(value);
       QString endExt=tmpInfo.suffix();
       //判断后缀名是否改变 并作出警告
      if(startExt!=endExt)
          {
      QMessageBox::StandardButton res= QMessageBox::warning(NULL,
                                           "warning", "后缀名改变可能会导致文件不可用!",
                                           QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
           if(res==QMessageBox::No)
             return;
           if(res==QMessageBox::Yes)
                model->setData(index, value, Qt::EditRole);
          }
        //qDebug()<<endExt;
}

效果图:

                    

4 编译过程的错误

      错误一: error:LNK2001  

       见 参考文献3 

      大部分原因是没有生成MOC文件, 该原因可能是没加Q_OBJECT  后加上之后 要清理项目 重新qmake


    错误二:error C2678: 二进制“=”: 没有找到接受“const QString”类型的左操作数的运算符(或没有可接受的转换)

                  查找了半天文献 发现了一篇有用的提示:参考文献4    const 成员函数不能改变类成员状态

                但我们明显希望修改startext成员变量来完成后缀名的改动检查。此时可以通过mutable修饰符来使其永远处于可变化状态(即使在const函数中)



参考文献:

   【1】QListWidget的item上实现右键菜单

   【2】视图与委托

   【3】LNK2001

   【4】const 函数





阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页