Search code examples
pythonpyqt4hotkeys

PyQt4 - how to disable all hot keys (native keyboard shortcuts)


I have a PyQt4 GUI that houses numerous libraries (such as Mayavi) which have their own internal keyboard shortcuts natively (already present without putting in any code to set them up). One such key is s in Mayavi - if you press this button while hovering over a Mayavi Figure, a save window will appear. Even worse, pressing the letter p while hovering over will completely freeze out all camera controls on that window.

I made a similar post back in April on how to turn off these shortcuts within one of these embedded libraries (Mayavi) - however, 5 months later and it appears such knowledge is very elusive.

Any help on this matter is greatly appreciated.


UPDATE: I've edited the original post based on forum feedback - very sorry for obfuscating this issue; hopefully the below code will prove more clear:

import sys, os
from pyface.qt import QtGui, QtCore
os.environ['ETS_TOOLKIT'] = 'qt4'
from traits.api import HasTraits,Instance,on_trait_change,Int
from traitsui.api import View,Item,VGroup
from mayavi import mlab
from mayavi.core.ui.api import MayaviScene, MlabSceneModel, SceneEditor

class Mayavi_Scene(HasTraits):
    scene = Instance(MlabSceneModel, ())

    @on_trait_change('scene.activated')
    def update_scene(self):
        Mayavi_Scene.fig1 = mlab.figure(1, bgcolor=(.5,.5,.5))
        self.scene.mlab.clf(figure=Mayavi_Scene.fig1)
        testPlot = mlab.test_contour3d()

    view = View(Item('scene', editor = SceneEditor(scene_class=MayaviScene),
                    height=300, width=300, show_label=False),
                resizable=True,
                )

class P1(QtGui.QWidget):    
    def __init__(self, parent=None):
        super(P1, self).__init__(parent)
        layout = QtGui.QGridLayout(self)

        self.label_avgVol = QtGui.QLabel('PyQt window without Mayavi')
        self.label_avgVol.setMargin(5)
        self.label_avgVol.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Sunken)
        self.label_avgVol.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)
        layout.addWidget(self.label_avgVol, 0, 0, 1, 3)
        self.label_avgVol.show()

class P2(QtGui.QWidget):    
    def __init__(self, parent=None):
        super(P2, self).__init__(parent)
        layout = QtGui.QGridLayout(self)

        self.label_edge1 = QtGui.QLabel('')
        self.label_edge1.setMargin(5)
        self.label_edge1.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Sunken)
        layout.addWidget(self.label_edge1, 0, 0, 4, 3)
        self.label_edge1.show()

        self.label_avgVol = QtGui.QLabel('PyQt window with Mayavi')
        self.label_avgVol.setMargin(5)
        self.label_avgVol.setFrameStyle(QtGui.QFrame.Box | QtGui.QFrame.Sunken)
        self.label_avgVol.setAlignment(QtCore.Qt.AlignCenter | QtCore.Qt.AlignVCenter)
        layout.addWidget(self.label_avgVol, 0, 0, 1, 3)
        self.label_avgVol.show()

        self.viz1 = Mayavi_Scene()
        self.ui1 = self.viz1.edit_traits(parent=self, kind='subpanel').control
        layout.addWidget(self.ui1, 1, 1, 1, 1)

        self.button = QtGui.QPushButton("Test", self)
        layout.addWidget(self.button, 2, 1, 1, 1)
        self.button.show()


class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        tab1 = P1(self)
        tab2 = P2(self)
        global tabs
        tabs = QtGui.QTabWidget(self)
        tabs.addTab(tab1, 'eventFilter works')
        tabs.addTab(tab2, 'eventFilter ignored')
        self.setCentralWidget(tabs)
        self.show()

        self.installEventFilter(self)

    def eventFilter(self, source, event):
        if event.type() == QtCore.QEvent.KeyPress:
            print('KeyPress: %s [%r]' % (event.key(), source))
            return True
            #event.ignore()

        return super(MainWindow, self).eventFilter(source, event)

if __name__ == '__main__':
    app = QtGui.QApplication.instance()
    w = MainWindow()
    sys.exit(app.exec_())

Solution

  • SOLUTION: Thanks to the very helpful individuals in the comments, the above code (in the original post) works as it is supposed to (or as best it can). There is apparently no way to control events on modules held within PyQt (such as Mayavi) through the PyQt event filter. However, if anyone is looking for the correct layout to control PyQt events alone, it has been supplied here.