是否可以通过单击项目在QTreeView中取消选择?

时间:2010-05-03 21:18:17

标签: qt pyqt qtreeview

我希望能够通过点击QTreeView中没有项目的部分来取消选择QTreeView中的项目,但我似乎无法找到这样做。我拦截了一个不在项目上的点击,但是QTreeView没有clicked信号,所以我无法弄清楚如何做到这一点。

8 个答案:

答案 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继承自QAbstractViewhttp://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

感谢您的回答:https://stackoverflow.com/a/1647616/1300519

答案 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)