matplotlib и Qt: нажатие мышью event.key всегда None
Я встроил фигуру matplotlib в приложение Qt (PySide) и хотел бы реагировать на события щелчка мыши в сочетании с клавишами-модификаторами (например, Shift и Control). В приведенном ниже коде я использовал метод canvas mpl_connect для подключения 'button_press_event' к фиктивному обработчику, который печатает значение event.key. Это значение всегда равно None, даже если я нажимаю клавишу-модификатор во время щелчка мышью. Как получить состояние клавиш-модификаторов в обработчике событий мыши matplotlib при встраивании фигуры matplotlib в приложение Qt?
Благодарю.
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_())
2 ответа
Решение, предоставленное ОП, отредактировано из ответа:
Я только что нашел ответ на свой вопрос здесь.
Проблема в том, что события нажатия клавиш в целом не обрабатываются, если вы "не активируете фокус qt на холсте mpl". Решение состоит в том, чтобы добавить две строки в класс MplWidget:
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)
event.key
используется при подключении key_press_event
здесь вы можете проверить event.button==1
(или 2 и т. д.)