标签:qtreeview qfilesystemmodel rename edit keypressevent
以前在写Markdown编辑器的时候, 写了一个基于QTreeView+QFileSystemModel的简单资源浏览器, 现在想给其增加一个rename的功能.
其实实现rename还是比较简单的, 首先在QTreeView中设置setEditTriggers(QAbstractItemView::EditKeyPressed);这样就可以按键盘上的F2来来进行rename. 但是如果想做成有一个右键菜单上有rename, 如下图:
那该怎么做呢. 这里需要加一个menu,当然并不是重点, 重点在于如何才会触发rename这个操作, 在前面我们设置好setEditTriggers之后按键盘F2是可以触发rename的.但是我们并不知道在按下F2之后发生了什么.当然我们可以完全不比理会按下F2之后发生了什么, 既然按下F2可以进行rename, 那么我们就产生一个按下F2的事件也是可以实现目的的代码片段如下:
connect(menu_, &ProjectExplorerMenu::signalRename, [this](){ QString path = model_->filePath(currentIndex()); if(path.isNull()) { qDebug() << "file path is null"; return; } //真逗比但有效... QKeyEvent event(QEvent::KeyPress, Qt::Key_F2, Qt::NoModifier); keyPressEvent(&event); });这里面当menu选中rename这一项的时候发出signalRename的信号, 在对应的槽中实例化了一个QKeyEvent对象, 并将其key设置为Qt::key_F2, 即产按下F2的这个事件, 然后把这个事件传给处理键盘按下的事件过滤器keyPressEvent. 就此目标实现. 但是这样做并不是太干净,想做得更干净一点可以查QTreeView的源码. 在QTreeView的keyPressEvent中:
void QTreeView::keyPressEvent(QKeyEvent *event) { Q_D(QTreeView); QModelIndex current = currentIndex(); //this is the management of the expansion if (d->isIndexValid(current) && d->model && d->itemsExpandable) { switch (event->key()) { case Qt::Key_Asterisk: { QStack<QModelIndex> parents; parents.push(current); while (!parents.isEmpty()) { QModelIndex parent = parents.pop(); for (int row = 0; row < d->model->rowCount(parent); ++row) { QModelIndex child = d->model->index(row, 0, parent); if (!d->isIndexValid(child)) break; parents.push(child); expand(child); } } expand(current); break; } case Qt::Key_Plus: expand(current); break; case Qt::Key_Minus: collapse(current); break; } } QAbstractItemView::keyPressEvent(event); }代码很简单没几行, 处理了按下键盘上+,-,*三个按键. +号展开, -号收缩, *号递归展开其他的键盘事件扔给其基类去处理(不看代码我都不知道原来已经有这样的处理........), 再来看看QAbstractItemView中对F2做了什么特别的处理这里代码就比较多了有几百行, 代码虽长但是F2处理的部分还是很简单的:
void QAbstractItemView::keyPressEvent(QKeyEvent *event) { ... switch (event->key()) { case Qt::Key_F2: if (!edit(currentIndex(), EditKeyPressed, event)) event->ignore(); break; ... } ... }原来按下F2的时候是使用了edit这个函数来进行处理的, 由此修改我们之前直接生成一个QKeyEvent实例并传递给keyPressEvent的代码可以更改为:
connect(menu_, &ProjectExplorerMenu::signalRename, [this](){ QString path = model_->filePath(currentIndex()); if(path.isNull()) { qDebug() << "file path is null"; return; } QKeyEvent event(QEvent::KeyPress, Qt::Key_F2, Qt::NoModifier); edit(currentIndex(), EditKeyPressed, &event); });
QTreeView + QFileSystemModel rename的实现
标签:qtreeview qfilesystemmodel rename edit keypressevent
原文地址:http://blog.csdn.net/slug302/article/details/39723895