Is it possible to deselect in a QTreeView by clicking off an item?

后端 未结 8 1173
盖世英雄少女心
盖世英雄少女心 2020-12-30 05:35

I\'d like to be able to deselect items in my QTreeView by clicking in a part of the QTreeView with no items in, but I can\'t seem to find anyway of doing this. I\'d intercep

相关标签:
8条回答
  • 2020-12-30 06:05

    QTreeView inherits from QAbstractView (http://doc.qt.digia.com/4.6/qtreeview.html) which has a clicked signal. The problem is that the signal is emitted only when index is valid so you can not achieve what you want with this signal.

    Try to intercept the mousePressEvent instead. In the function you can find where the user has clicked and deselect selected item if needed.

    0 讨论(0)
  • 2020-12-30 06:09

    Based on @Eric's solution, and as it only deselects if the clicked item was selected, here is what I came up with. This solution also works when you click the blank area of the 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
    

    Yassir

    0 讨论(0)
  • 2020-12-30 06:12

    To add to @Skilldrick's answer, if you need to apply this to a view that has already been instantiated because you're using Qt Designer, you can do something like this:

    import new
    def mousePressEvent(self, event):
        self.clearSelection()
        QtGui.QTableView.mousePressEvent(self, event)
    self.ui.tableView.mousePressEvent = new.instancemethod(mousePressEvent, self.ui.tableView, None)
    

    This assumes that your view is self.ui.tableView.

    Thanks to this answer: https://stackoverflow.com/a/1647616/1300519

    0 讨论(0)
  • 2020-12-30 06:13

    The clearSelection does not work in my case. I'm using treeviews with a singleselection mode. Here is what I've coded:

    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);
        }
    
    };
    

    This works really fine.

    Eric

    0 讨论(0)
  • 2020-12-30 06:16

    This is actually quite simple (in PyQt):

    class DeselectableTreeView(QtGui.QTreeView):
        def mousePressEvent(self, event):
            self.clearSelection()
            QtGui.QTreeView.mousePressEvent(self, event)
    

    Qt uses mousePressEvent to emit clicked. If you clear the selection before sending on the event, then if an item is clicked it will be selected, otherwise nothing will be selected. Many thanks to Patrice for helping me out with this one :)

    0 讨论(0)
  • 2020-12-30 06:27

    Since the question is specifically about PyQt, I'd like to add this based on the answer by Nick Pruehs and the comment by ekhumoro, the simplest way to achieve this:

    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)
    
    0 讨论(0)
提交回复
热议问题