Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib and Qt: mouse press event.key is always None

I embedded a matplotlib figure in a Qt (PySide) application and I would like to respond to mouse click events in combination with modifier keys (e.g. shift and control). In the code below I used the canvas mpl_connect method to connect 'button_press_event' to a dummy handler that prints the value of event.key. This value is always 'None' even if I press a modifier key during the mouse click. How can I get the state of modifier keys in a matplotlib mouse event handler when embedding a matplotlib figure in a Qt application?

Thanks.

import sys

from PySide import QtGui, QtCore

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure

class MplCanvas(FigureCanvas):
    """Class to represent the FigureCanvas widget"""
    def __init__(self):
        self.fig = Figure()        
        self.ax = self.fig.add_subplot(111)

        FigureCanvas.__init__(self, self.fig)
        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

        self.fig.canvas.mpl_connect('button_press_event',self._on_press)

    def _on_press(self,event):
        print( event.key )


class MplWidget(QtGui.QWidget):
    """Widget defined in Qt Designer"""
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)

        self.canvas = MplCanvas()

        self.vbl = QtGui.QVBoxLayout()
        self.vbl.addWidget(self.canvas)

        self.setLayout(self.vbl)


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName("verticalLayout")
        self.mpl = MplWidget(self.centralwidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.mpl.sizePolicy().hasHeightForWidth())
        self.mpl.setSizePolicy(sizePolicy)
        self.mpl.setObjectName("mpl")
        self.verticalLayout.addWidget(self.mpl)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8))

class DesignerMainWindow(QtGui.QMainWindow, Ui_MainWindow):
    """Customization for Qt Designer created window"""
    def __init__(self, parent = None):
        super(DesignerMainWindow, self).__init__(parent)
        # setup the GUI --> function generated by pyuic4
        self.setupUi(self)


if __name__ == '__main__':

    # create the GUI application
    app = QtGui.QApplication(sys.argv)
    # instantiate the main window
    dmw = DesignerMainWindow()
    # show it
    dmw.show()
    # start the Qt main loop execution, exiting from this script
    # with the same return code of Qt application
    sys.exit(app.exec_())
like image 673
user3083667 Avatar asked Oct 20 '22 13:10

user3083667


1 Answers

Solution, provided by OP, edited out of the answer:

I just found the answer to my question here.
The issue is that key press events in general are not processed unless you "activate the focus of qt onto your mpl canvas". The solution is to add two lines to the MplWidget class:

class MplWidget(QtGui.QWidget):
    """Widget defined in Qt Designer"""
    def __init__(self, parent = None):
        QtGui.QWidget.__init__(self, parent)

        self.canvas = MplCanvas()

        #THESE TWO LINES WERE ADDED
        self.canvas.setFocusPolicy( QtCore.Qt.ClickFocus )
        self.canvas.setFocus()

        self.vbl = QtGui.QVBoxLayout()
        self.vbl.addWidget(self.canvas)

        self.setLayout(self.vbl)
like image 60
2 revs Avatar answered Oct 23 '22 10:10

2 revs