我希望能够通过点击QTreeView中没有项目的部分来取消选择QTreeView中的项目,但我似乎无法找到这样做。我拦截了一个不在项目上的点击,但是QTreeView没有clicked
信号,所以我无法弄清楚如何做到这一点。
答案 0 :(得分:14)
基于@ Eric的解决方案,因为它只取消选择是否选中了点击的项目,这就是我想出的。 单击QTreeView的空白区域
时,此解决方案也可以使用#ifndef DESELECTABLETREEVIEW_H
#define DESELECTABLETREEVIEW_H
#include "QTreeView"
#include "QMouseEvent"
#include "QDebug"
class DeselectableTreeView : public QTreeView
{
public:
DeselectableTreeView(QWidget *parent) : QTreeView(parent) {}
virtual ~DeselectableTreeView() {}
private:
virtual void mousePressEvent(QMouseEvent *event)
{
QModelIndex item = indexAt(event->pos());
bool selected = selectionModel()->isSelected(indexAt(event->pos()));
QTreeView::mousePressEvent(event);
if ((item.row() == -1 && item.column() == -1) || selected)
{
clearSelection();
const QModelIndex index;
selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select);
}
}
};
#endif // DESELECTABLETREEVIEW_H
亚瑟尔
答案 1 :(得分:10)
这实际上非常简单(在PyQt中):
class DeselectableTreeView(QtGui.QTreeView):
def mousePressEvent(self, event):
self.clearSelection()
QtGui.QTreeView.mousePressEvent(self, event)
Qt使用mousePressEvent
发出clicked
。如果在发送事件之前清除选择,则如果单击某个项目,则会选择该项目,否则将不会选择任何项目。非常感谢Patrice帮助我解决这个问题:)
答案 2 :(得分:8)
clearSelection在我的情况下不起作用。我正在使用具有单选模式的树视图。这是我编码的内容:
class DeselectableTreeView : public QTreeView
{
public:
DeselectableTreeView(QWidget *parent) : QTreeView(parent) {}
virtual ~DeselectableTreeView() {}
private:
virtual void mousePressEvent(QMouseEvent *event)
{
QModelIndex item = indexAt(event->pos());
bool selected = selectionModel()->isSelected(item);
QTreeView::mousePressEvent(event);
if (selected)
selectionModel()->select(item, QItemSelectionModel::Deselect);
}
};
这很好用。
埃里克
答案 3 :(得分:7)
QTreeView
继承自QAbstractView
(http://doc.qt.digia.com/4.6/qtreeview.html),其信号为clicked
。问题是只有在索引有效时才会发出信号,因此无法通过此信号实现所需的信号。
尝试拦截mousePressEvent
。在该功能中,您可以找到用户点击的位置,并根据需要取消选择所选项目。
答案 4 :(得分:1)
要添加到 @Skilldrick 的答案,如果您需要将此应用于已经实例化的视图,因为您正在使用Qt Designer,您可以执行某些操作像这样:
import new
def mousePressEvent(self, event):
self.clearSelection()
QtGui.QTableView.mousePressEvent(self, event)
self.ui.tableView.mousePressEvent = new.instancemethod(mousePressEvent, self.ui.tableView, None)
这假定您的观点为self.ui.tableView
。
答案 5 :(得分:1)
在@Skilldrick的回答中,我们冒着发送多余事件的风险。如果已经选择了某个项目,并且我们再次点击该项目,则会提升取消选择和选择的事件。基于应用程序中的其他侦听器,这可能不是您想要的。
@ eric-maeker的解决方案只有在我们选中它时再次点击它时才会取消选择。严格来说,这不是原始问题的答案,即在单击其他地方时如何取消选择所选项目。
@ yassir-ennazk接近,但正如@ adrian-maire指出的那样,解决方案并非最佳。 event->pos()
评估两次。此外,始终通过调用QTreeView::mousePressEvent
评估鼠标事件。
根据上面提到的其他答案,我已经提出了解决方案。如果我们在存在另一个树视图项的位置点击,则通过将事件转发到TreeView
来选择新项目。如果没有,我们将清除选择。
请注意,这也适用于QTreeWidget
。
virtual void mousePressEvent(QMouseEvent* event)
{
QModelIndex item = indexAt(event->pos());
if (item.isValid())
{
QTreeView::mousePressEvent(event);
}
else
{
clearSelection();
const QModelIndex index;
selectionModel()->setCurrentIndex(index, QItemSelectionModel::Select);
}
}
答案 6 :(得分:0)
您可以尝试为小部件设置不同的selection mode。我不知道他们中的任何一个是否完全覆盖了你想要的东西(单选,但是可以选择)。
答案 7 :(得分:0)
由于问题是关于PyQt的,因此我想根据Nick Pruehs的回答和ekhumoro的评论(这是实现此目的的最简单方法)添加该问题:
class TreeView(QTreeView):
def __init__(self, *args, **kwds):
QTreeView.__init__(self, *args, **kwds)
def mousePressEvent(self, event):
item = self.indexAt(event.pos())
if not item.isValid():
self.clearSelection()
QTreeView.mousePressEvent(self, event)