BarPlotDemo.py

#!/usr/bin/env python
# Contributed by Tomaz Curk in a bug report showing that the stack order of the
# curves was dependent on the number of curves. This has been fixed in Qwt.
#
# BarCurve is an idea of Tomaz Curk.
#
# Beautified and expanded by Gerard Vermeulen.
# for debugging, requires: python configure.py --trace ...
if False:
 import sip
 sip.settracemask(0x3f)
import random
import sys
import PyQt4.Qt as Qt
import PyQt4.Qwt5 as Qwt
class Spy(Qt.QObject):
 
 def __init__(self, parent):
 Qt.QObject.__init__(self, parent)
 parent.setMouseTracking(True)
 parent.installEventFilter(self)
 # __init__()
 def eventFilter(self, _, event):
 if event.type() == Qt.QEvent.MouseMove:
 self.emit(Qt.SIGNAL("MouseMove"), event.pos())
 return False
 # eventFilter()
# class Spy
class BarCurve(Qwt.QwtPlotCurve):
 def __init__(self, penColor=Qt.Qt.black, brushColor=Qt.Qt.white):
 Qwt.QwtPlotCurve.__init__(self)
 self.penColor = penColor
 self.brushColor = brushColor
 
 # __init__()
 
 def drawFromTo(self, painter, xMap, yMap, start, stop):
 """Draws rectangles with the corners taken from the x- and y-arrays.
 """
 painter.setPen(Qt.QPen(self.penColor, 2))
 painter.setBrush(self.brushColor)
 if stop == -1:
 stop = self.dataSize()
 # force 'start' and 'stop' to be even and positive
 if start & 1:
 start -= 1
 if stop & 1:
 stop -= 1
 start = max(start, 0)
 stop = max(stop, 0)
 for i in range(start, stop, 2):
 px1 = xMap.transform(self.x(i))
 py1 = yMap.transform(self.y(i))
 px2 = xMap.transform(self.x(i+1))
 py2 = yMap.transform(self.y(i+1))
 painter.drawRect(px1, py1, (px2 - px1), (py2 - py1))
 # drawFromTo()
# class BarCurve
class BarPlotMainWindow(Qt.QMainWindow):
 colors = (Qt.Qt.red,
 Qt.Qt.green,
 Qt.Qt.blue,
 Qt.Qt.cyan,
 Qt.Qt.magenta,
 Qt.Qt.yellow,
 )
 def __init__(self, parent=None):
 Qt.QMainWindow.__init__(self, parent)
 # Initialize a QwPlot central widget
 self.plot = Qwt.QwtPlot(self)
 self.plot.setTitle('left-click & drag to zoom')
 self.plot.setCanvasBackground(Qt.Qt.white)
 self.plot.plotLayout().setCanvasMargin(0)
 self.plot.plotLayout().setAlignCanvasToScales(True)
 self.setCentralWidget(self.plot)
 grid = Qwt.QwtPlotGrid()
 pen = Qt.QPen(Qt.Qt.DotLine)
 pen.setColor(Qt.Qt.black)
 pen.setWidth(0)
 grid.setPen(pen)
 grid.attach(self.plot)
 self.__initTracking()
 self.__initZooming()
 self.__initToolBar()
 
 # Finalize
 self.counter.setValue(10)
 self.go(self.counter.value())
 # __init__()
 def __initTracking(self):
 """Initialize tracking
 """ 
 self.connect(Spy(self.plot.canvas()),
 Qt.SIGNAL("MouseMove"),
 self.showCoordinates) 
 self.statusBar().showMessage(
 'Mouse movements in the plot canvas are shown in the status bar')
 # __initTracking()
 def showCoordinates(self, position):
 self.statusBar().showMessage(
 'x = %+.6g, y = %.6g'
 % (self.plot.invTransform(Qwt.QwtPlot.xBottom, position.x()),
 self.plot.invTransform(Qwt.QwtPlot.yLeft, position.y())))
 # showCoordinates()
 
 def __initZooming(self):
 """Initialize zooming
 """
 self.zoomer = Qwt.QwtPlotZoomer(Qwt.QwtPlot.xBottom,
 Qwt.QwtPlot.yLeft,
 Qwt.QwtPicker.DragSelection,
 Qwt.QwtPicker.AlwaysOff,
 self.plot.canvas())
 self.zoomer.setRubberBandPen(Qt.QPen(Qt.Qt.black))
 # __initZooming()
 
 def setZoomerMousePattern(self, index):
 """Set the mouse zoomer pattern.
 """
 if index == 0:
 pattern = [
 Qwt.QwtEventPattern.MousePattern(Qt.Qt.LeftButton,
 Qt.Qt.NoModifier),
 Qwt.QwtEventPattern.MousePattern(Qt.Qt.MidButton,
 Qt.Qt.NoModifier),
 Qwt.QwtEventPattern.MousePattern(Qt.Qt.RightButton,
 Qt.Qt.NoModifier),
 Qwt.QwtEventPattern.MousePattern(Qt.Qt.LeftButton,
 Qt.Qt.ShiftModifier),
 Qwt.QwtEventPattern.MousePattern(Qt.Qt.MidButton,
 Qt.Qt.ShiftModifier),
 Qwt.QwtEventPattern.MousePattern(Qt.Qt.RightButton,
 Qt.Qt.ShiftModifier),
 ]
 self.zoomer.setMousePattern(pattern)
 elif index in (1, 2, 3):
 self.zoomer.initMousePattern(index)
 else:
 raise ValueError, 'index must be in (0, 1, 2, 3)'
 # setZoomerMousePattern()
 def __initToolBar(self):
 """Initialize the toolbar
 """
 
 toolBar = Qt.QToolBar(self)
 self.addToolBar(toolBar)
 toolBar.addWidget(Qt.QLabel('Bars', toolBar))
 self.counter = Qwt.QwtCounter(toolBar)
 self.counter.setRange(0, 10000, 1)
 self.counter.setNumButtons(3)
 toolBar.addWidget(self.counter)
 toolBar.addSeparator()
 toolBar.addWidget(Qt.QLabel('Mouse', toolBar))
 mouseComboBox = Qt.QComboBox(toolBar)
 for name in ('3 buttons (PyQwt)',
 '1 button',
 '2 buttons',
 '3 buttons (Qwt)'):
 mouseComboBox.addItem(name)
 mouseComboBox.setCurrentIndex(0)
 toolBar.addWidget(mouseComboBox)
 toolBar.addSeparator()
 self.setZoomerMousePattern(0)
 toolBar.addAction(Qt.QWhatsThis.createAction(toolBar))
 self.plot.canvas().setWhatsThis(
 'A QwtPlotZoomer lets you zoom infinitely deep '
 'by saving the zoom states on a stack.\n\n'
 'You can:\n'
 '- select a zoom region\n'
 '- unzoom all\n'
 '- walk down the stack\n'
 '- walk up the stack.\n\n'
 'The combo box in the toolbar lets you attach '
 'different sets of mouse events to those actions.'
 )
 
 self.counter.setWhatsThis(
 'Select the number of bars'
 )
 
 mouseComboBox.setWhatsThis(
 'Configure the zoomer mouse buttons.\n\n'
 '3 buttons (PyQwt style):\n'
 '- left-click & drag to zoom\n'
 '- middle-click to unzoom all\n'
 '- right-click to walk down the stack\n'
 '- shift-right-click to walk up the stack.\n'
 '1 button:\n'
 '- click & drag to zoom\n'
 '- control-click to unzoom all\n'
 '- alt-click to walk down the stack\n'
 '- shift-alt-click to walk up the stack.\n'
 '2 buttons:\n'
 '- left-click & drag to zoom\n'
 '- right-click to unzoom all\n'
 '- alt-left-click to walk down the stack\n'
 '- alt-shift-left-click to walk up the stack.\n'
 '3 buttons (Qwt style):\n'
 '- left-click & drag to zoom\n'
 '- right-click to unzoom all\n'
 '- middle-click to walk down the stack\n'
 '- shift-middle-click to walk up the stack.\n\n'
 'If some of those key combinations interfere with '
 'your Window manager, press the:\n'
 '- escape-key to unzoom all\n'
 '- minus-key to walk down the stack\n'
 '- plus-key to walk up the stack.'
 )
 self.connect(self.counter,
 Qt.SIGNAL('valueChanged(double)'),
 self.go)
 self.connect(mouseComboBox,
 Qt.SIGNAL('activated(int)'),
 self.setZoomerMousePattern)
 # __initToolBar()
 def go(self, value):
 """Create and plot a sequence of bars taking into account the controls
 """
 n = int(value)
 for bar in self.plot.itemList():
 if isinstance(bar, BarCurve):
 bar.detach()
 for i in range(n):
 bar = BarCurve(
 self.colors[random.randint(0, len(self.colors)-1)],
 self.colors[random.randint(0, len(self.colors)-1)],
 )
 bar.attach(self.plot)
 bar.setData([i, i+1.4], [0.3*i, 5.0+0.3*i])
 self.clearZoomStack()
 # go()
 def clearZoomStack(self):
 """Auto scale and clear the zoom stack
 """
 self.plot.setAxisAutoScale(Qwt.QwtPlot.xBottom)
 self.plot.setAxisAutoScale(Qwt.QwtPlot.yLeft)
 self.plot.replot()
 self.zoomer.setZoomBase()
 # clearZoomStack()
 
# class BarPlotMainWindow
def make():
 demo = BarPlotMainWindow()
 demo.resize(500, 500)
 demo.show()
 return demo
# make()
def main(args):
 app = Qt.QApplication(args)
 demo = make()
 sys.exit(app.exec_())
# main()
# Admire!
if __name__ == '__main__':
 main(sys.argv)
# Local Variables: ***
# mode: python ***
# End: ***

AltStyle によって変換されたページ (->オリジナル) /