标签: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