Search code examples
qtkey-bindingsmayaqtreeviewqtreewidget

How Do I Disable the Select All QTreeView Key Binding


I have QTreeWidget in a widget in Maya (A 3D computer graphics application). The problem is, my widget is not only blocking the native CTRL+A hotkey, it is selecting everything in my tree. How can I let this hot key bubble up to the parent application?

I am already using event filters for a lot of custom key handling, but it seems like the tree wants to handle this one for me. I like the arrow key functionality, so i don't want to disable all key bindings, but if I have to, I will... if I knew how

Cheers,

P.S. Something similar was asked here but the answer ignores the question: qt: I would like to disable the key bindings automatically set for a QTreeView


Here is A solution in Python for a QTreeWidget.

I can't decided if this is the dirtiest thing I have ever done with Python or just a nifty Python version of an extension method! (It feels like the former.)

The problem is, I don't actually have the QTreeView class. It was added in designer with the name "tree", so I literally overrode the method then call the base functionality from my method...

def __init__ #...snip...
    self.tree.keyPressEvent = self.onKeyPressEvent # Replace with my method


def onKeyPressEvent(self, event):
    if event.key() == Qt.Key_A and event.modifiers() == Qt.ControlModifier:
        event.ignore()  # Allows fall-through to the parent
        return

    QtGui.QTreeView.keyPressEvent(self.tree, event)  # All other behaviors handled

...so that is just too dirty for me. I knew there had to be a solution to this common situation (not having a subclass). I am already using event filters, so I tried it and it worked. The key was knowing where the event was being handled and using both event.ignore() as well as returning True to allow the event to bubble up and block the KeyPressEvent for CTRL+A.

def eventFilter(self, obj, event):
    # Filter out all non-KeyPress events
    if not event.type() == QEvent.KeyPress:
        return False

    if event.key() == Qt.Key_A and event.modifiers() == Qt.ControlModifier:
        event.ignore()  # Allows fall-through to the parent
        return True     # Block the tree's KeyPressEvent

    return False        # Do nothing

Solution

  • Reimplement the keyPressEvent, and when CTRL+A is pressed, ignore the event.

    The code should then look similar to this:

    MyTreeView::keyPressEvent(QKeyEvent *e)
    {
        if(e->key() == Qt::Key_A && e->modifiers() == Qt::ControlModifier)
        {
            e->ignore();
            QWidget::keyPressEvent(e); // Not sure about this. Please try and report!
        }
        else
            QTreeView::keyPressEvent(e);
    }