pyqt - Programmatically change matplotlib toolbar mode in Qt4 -
i'm building application using matplotlib version 1.2.1, qt4.7, python 2.7.
i want modify matplotlib toolbar add checkable button sets mode selecting data points in response pick event. works, except pick event not sent when zoom or pan navigation buttons selected.
what looking way programmatically turn off pan , zoom modes. thought able setting checked state of toolbar pan , zoom buttons false. appears work (for example if zoom button checked, setting false makes appear unchecked). not change mode of canvas - cursor still zoom cursor, , pick event doesn't fire.
the following code demonstrates this:
import sys, os, math pyqt4.qtcore import * pyqt4.qtgui import * import matplotlib matplotlib.backends.backend_qt4agg import figurecanvasqtagg matplotlib.backends.backend_qt4agg import navigationtoolbar2qtagg matplotlib.figure import figure class navigationtoolbar( navigationtoolbar2qtagg ): picked=pyqtsignal(int,name='picked') def __init__(self, canvas, parent ): navigationtoolbar2qtagg.__init__(self,canvas,parent) self.clearbuttons=[] # search through existing buttons # next use placement of custom button next=none c in self.findchildren(qtoolbutton): if next none: next=c # don't want see subplots , customize if str(c.text()) in ('subplots','customize'): c.defaultaction().setvisible(false) continue # need keep track of pan , zoom buttons # grab toggled event clear checked status of picker button if str(c.text()) in ('pan','zoom'): c.toggled.connect(self.clearpicker) self.clearbuttons.append(c) next=none # create custom button pm=qpixmap(32,32) pm.fill(qapplication.palette().color(qpalette.normal,qpalette.button)) painter=qpainter(pm) painter.fillrect(6,6,20,20,qt.red) painter.fillrect(15,3,3,26,qt.blue) painter.fillrect(3,15,26,3,qt.blue) painter.end() icon=qicon(pm) picker=qaction("pick",self) picker.seticon(icon) picker.setcheckable(true) picker.settooltip("pick data point") self.picker = picker button=qtoolbutton(self) button.setdefaultaction(self.picker) # add toolbar, , connect event self.insertwidget(next.defaultaction(),button) picker.toggled.connect(self.pickertoggled) # grab picked event canvas canvas.mpl_connect('pick_event',self.canvaspicked) def clearpicker( self, checked ): if checked: self.picker.setchecked(false) def pickertoggled( self, checked ): if checked: c in self.clearbuttons: c.defaultaction().setchecked(false) self.set_message('reject/use observation') def canvaspicked( self, event ): if self.picker.ischecked(): self.picked.emit(event.ind) class mainwindow(qmainwindow): def __init__(self, parent=none): qmainwindow.__init__(self, parent) self.x=[i*0.1 in range(30)] self.y=[math.sin(x) x in self.x] self.picked=[] self.setwindowtitle('custom toolbar') self.frame = qwidget() self.fig = figure((4.0, 4.0)) self.canvas = figurecanvasqtagg(self.fig) self.canvas.setparent(self.frame) self.axes = self.fig.add_subplot(111) # create navigation toolbar, tied canvas # , link clicked event self.toolbar = navigationtoolbar(self.canvas, self.frame) self.toolbar.picked.connect(self.addpoint) vbox = qvboxlayout() vbox.addwidget(self.canvas) vbox.addwidget(self.toolbar) self.frame.setlayout(vbox) self.setcentralwidget(self.frame) self.draw() def draw(self): while self.axes.lines: self.axes.lines[0].remove() self.axes.plot(self.x,self.y,'b+',picker=5) xp=[self.x[i] in self.picked] yp=[self.y[i] in self.picked] self.axes.plot(xp,yp,'rs') self.canvas.draw() def addpoint(self,index): if index in self.picked: self.picked.remove(index) else: self.picked.append(index) self.draw() if __name__ == "__main__": app = qapplication(sys.argv) form = mainwindow() form.show() app.exec_()
if read source code of navigationtoolbar2qt
, can find that:
_active
current state of pan , zoom.- call
pan()
,zoom()
method toggle state.
so, here code disable pan & zoom:
def pickertoggled( self, checked ): if checked: if self._active == "pan": self.pan() elif self._active == "zoom": self.zoom() self.set_message('reject/use observation')
Comments
Post a Comment