Я новый пользователь этого сообщества stackoverflow. Я борюсь от дней с некоторыми проблемами в моем коде, которые я не могу понять. В моем следующем коде я пытаюсь определить пользовательский инструмент селектора для моего графического интерфейса. Я воспроизвел «ошибку» и основную структуру моей программы). Я пытаюсь подключить сигнал matplotlib с помощью «mpl_connect» structor, но, к сожалению, сигнал нажатия кнопки, отпускания и движения мыши, а относительные методы, похоже, неактивны для класса холста. Вот неработающий код.Конструкция PyQt4 "mpl_connect" не работает через классы
import sys
from PyQt4 import QtGui,QtCore
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.setupUi(self)
def setupUi(self,parent):
self.canvas=MyCanvas(self)
self.toolbar=MyToolBar(self.canvas,self)
self.addToolBar(QtCore.Qt.BottomToolBarArea,parent.toolbar)
class MyCanvas(FigureCanvas):
def __init__(self,parent):
self.fig=Figure()
FigureCanvas.__init__(self, self.fig)
FigureCanvas.setSizePolicy(self,
QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.setParent(parent)
class MyToolBar(QtGui.QToolBar):
def __init__(self,canvas,parent):
super(MyToolBar,self).__init__(parent)
#
self.PICK_act=QtGui.QAction("PUSH ME!!",parent,checkable=True)
self.PICK_act.toggled.connect(lambda: self.pickData(canvas))
#
self.addAction(self.PICK_act)
self.addSeparator()
## Creating the matplotlib toolbar
self.mpl_tool=NavigationToolbar(canvas,parent)
## Merge the two toolbar
self.addWidget(self.mpl_tool)
def pickData(self,canvas):
P=Picker(canvas)
if self.PICK_act.isChecked():
print "CHECKED"
P._activation(True)
else:
print "NOT CHECKED"
P._activation(False)
class Picker(object):
def __init__(self,canvas):
self.index=None
self.is_pressed=None
# To define the event of PickData_ACTION
self.canvas=canvas
###
self.selPressEvent=None
self.selReleaseEvent=None
self.selMoveEvent=None
def _activation(self,condition):
if condition==True:
self.selPressEvent=self.canvas.mpl_connect('button_press_event',self.onpress)
self.selReleaseEvent=self.canvas.mpl_connect('button_release_event',self.onrelease)
self.selMoveEvent=self.canvas.mpl_connect('motion_notify_event',self.onmotion)
print "Picker ON"
return True
else:
self.canvas.mpl_disconnect(self.selPressEvent)
self.canvas.mpl_disconnect(self.selReleaseEvent)
self.canvas.mpl_disconnect(self.selMoveEvent)
print "Picker OFF"
return False
def onpress(self,event):
print "..clicked"
self.x0 = event.xdata
self.y0 = event.ydata
self.is_pressed=True
def onrelease(self,event):
print "...released"
self.x1 = event.xdata
self.y1 = event.ydata
self.is_pressed=False
def onmotion(self,event):
if self.is_pressed==True:
print "moving"
# =========================================================================
def run():
App=QtGui.QApplication(sys.argv)
GUI=Example()
GUI.show()
sys.exit(App.exec_())
#
run()
Если вместо этого я определяю те же методы внутри класса «MyCanvas», они будут работать. Рабочий код заключается в следующем:
import sys
from PyQt4 import QtGui,QtCore
from matplotlib.figure import Figure
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg import NavigationToolbar2QT as NavigationToolbar
class Example(QtGui.QMainWindow):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.setupUi(self)
def setupUi(self,parent):
self.canvas=MyCanvas(self)
self.toolbar=MyToolBar(self.canvas,self)
self.addToolBar(QtCore.Qt.BottomToolBarArea,parent.toolbar)
class MyCanvas(FigureCanvas):
def __init__(self,parent):
self.fig=Figure()
FigureCanvas.__init__(self, self.fig)
FigureCanvas.setSizePolicy(self,
QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
self.setParent(parent)
###
self.selPressEvent=None
self.selReleaseEvent=None
self.selMoveEvent=None
def onpress(self,event):
print "MyCanvas::onpress ---> clicked"
def onrelease(self,event):
print "MyCanvas::onrelease ---> release"
def onmotion(self,event):
print "MyCanvas::onmotion ---> motion"
class MyToolBar(QtGui.QToolBar):
def __init__(self,canvas,parent):
super(MyToolBar,self).__init__(parent)
#
self.PICK_act=QtGui.QAction("PUSH ME!!",parent,checkable=True)
self.PICK_act.toggled.connect(lambda: self.pickData(canvas))
#
self.addAction(self.PICK_act)
self.addSeparator()
## Creating the matplotlib toolbar
self.mpl_tool=NavigationToolbar(canvas,parent)
## Merge the two toolbar
self.addWidget(self.mpl_tool)
def pickData(self,canvas):
P=Picker(canvas)
if self.PICK_act.isChecked():
print "CHECKED"
P._activation(True)
else:
print "NOT CHECKED"
P._activation(False)
class Picker(object):
def __init__(self,canvas):
self.index=None
self.is_pressed=None
# To define the event of PickData_ACTION
self.canvas=canvas
def _activation(self,condition):
if condition==True:
self.canvas.selPressEvent=self.canvas.mpl_connect('button_press_event',self.canvas.onpress)
self.canvas.selReleaseEvent=self.canvas.mpl_connect('button_release_event',self.canvas.onrelease)
self.canvas.selMoveEvent=self.canvas.mpl_connect('motion_notify_event',self.canvas.onmotion)
print "Picker ON"
return True
else:
self.canvas.mpl_disconnect(self.canvas.selPressEvent)
self.canvas.mpl_disconnect(self.canvas.selReleaseEvent)
self.canvas.mpl_disconnect(self.canvas.selMoveEvent)
print "Picker OFF"
return False
def onpress(self,event):
print "..clicked"
self.x0 = event.xdata
self.y0 = event.ydata
self.is_pressed=True
def onrelease(self,event):
print "...released"
self.x1 = event.xdata
self.y1 = event.ydata
self.is_pressed=False
def onmotion(self,event):
if self.is_pressed==True:
print "moving"
# =========================================================================
def run():
App=QtGui.QApplication(sys.argv)
GUI=Example()
GUI.show()
sys.exit(App.exec_())
#
run()
мне нужно держать «Picker» и относительные методы, отделенные от «MyCanvas» класса для ясности. Но я действительно не могу понять, что происходит в моем первом коде: не так. Сигнал кажется испущенным, но не получен. В STDERR не сообщается об ошибке. Я думаю, что я правильно отношусь к определению классов/методов. Любая помощь будет оценена по достоинству. Заранее большое спасибо.
EDIT РЕШЕНИЕ: Для кого это может касаться, я решил проблему инициализации сборщика в в «MyToolbar» класс:
self.Picker=Picker(canvas)
def pickData(self,canvas):
if self.PICK_act.isChecked():
print "CHECKED"
self.Picker._activation(True)
else:
print "NOT CHECKED"
self.Picker._activation(False)
Для справок в будущем, чем меньше кода в вашем вопросе, тем лучше. Вам нужно только один из вызовов подключения, чтобы показать проблему и в рабочем случае, помещая панель инструментов на панели инструментов, а не вниз в 'Picker'. Чем проще понять ваш код, тем полезнее он будет для будущих читателей (поскольку они могут сказать, что у них такая же проблема) и с большей вероятностью получить ответ (поскольку люди будут более легко понимать, что вы делаете/пытаетесь сделать). – tacaswell