示例#1
0
class InteractiveGRWidget(GRWidget):

    logXinDomain = QtCore.Signal(bool)
    logYinDomain = QtCore.Signal(bool)
    modePick = QtCore.Signal(bool)

    GESTURE_RECOGNIZERS = [PanGestureRecognizer, SelectGestureRecognizer]

    def __init__(self, *args, **kwargs):
        super(InteractiveGRWidget, self).__init__(*args, **kwargs)
        self._recognizers = []
        # register gesture recognizers
        for recognizer in self.GESTURE_RECOGNIZERS:
            instance = recognizer()
            self.grabGesture(recognizer.registerRecognizer(instance))
            # keep a reference on existing QGestureRecognizers in order
            # to circumvent that they will be accidentially freed when
            # using PyQt4 versions which will not handle the membership
            # correctly, e.g. PyQt4 4.9.1 shipped with Ubuntu 12.04.
            self._recognizers.append(instance)

        self._eventFilter = installEventFilter(self)
        self._eventFilterEnabled = True
        self.cbm.addHandler(MouseEvent.MOUSE_MOVE, self.mouseMove)
        self.cbm.addHandler(MouseEvent.MOUSE_PRESS, self.mousePress)
        self.cbm.addHandler(MouseEvent.MOUSE_RELEASE, self.mouseRelease)
        self.cbm.addHandler(WheelEvent.WHEEL_MOVE, self.wheelMove)
        self.cbm.addHandler(PickEvent.PICK_MOVE, self.pickMove)
        self.cbm.addHandler(MouseGestureEvent.MOUSE_PAN, self._mousePan)
        self.cbm.addHandler(MouseGestureEvent.MOUSE_SELECT, self._mouseSelect)
        self.setMouseTracking(True)
        self._tselect = None  # select point tuple
        self._logXinDomain = None
        self._logYinDomain = None
        self._pickMode = False
        self._pickEvent = None
        self._selectEnabled, self._panEnabled = True, True
        self._roiEnabled = True
        self._zoomEnabled = True
        self._lstPlot = []

    def draw(self, clear=None, update=None):
        # obsolete kwargs clear, update (unused) just kept for compatibility
        GRWidget.draw(self, clear, update)
        gr.setwsviewport(0, self.mwidth, 0, self.mheight)
        gr.setwswindow(0, self.sizex, 0, self.sizey)

        for plot in self._lstPlot:
            plot.sizex, plot.sizey = self.sizex, self.sizey
            plot.drawGR()
            # logDomainCheck
            logXinDomain = plot.logXinDomain()
            logYinDomain = plot.logYinDomain()
            if logXinDomain != self._logXinDomain:
                self._logXinDomain = logXinDomain
                self.logXinDomain.emit(self._logXinDomain)
            if logYinDomain != self._logYinDomain:
                self._logYinDomain = logYinDomain
                self.logYinDomain.emit(self._logYinDomain)

        if self._pickEvent:
            event = self._pickEvent
            gr.setviewport(*event.viewportscaled)
            wcPoint = event.getWC(event.viewport)
            window = gr.inqwindow()
            gr.setwindow(*event.getWindow())
            gr.setmarkertype(gr.MARKERTYPE_PLUS)
            gr.polymarker([wcPoint.x], [wcPoint.y])
            gr.setwindow(*window)

    def addPlot(self, *args, **kwargs):
        for plot in args:
            if plot and plot not in self._lstPlot:
                self._lstPlot.append(plot)
        self.update()
        return self._lstPlot

    @property
    def cbm(self):
        """Get CallbackManager used by EventFilter"""
        return self._eventFilter.manager

    def setEventFilterEnabled(self, flag):
        """Dis-/Enable QtGR events"""
        if self._eventFilterEnabled:
            if not flag:
                self.removeEventFilter(self._eventFilter)
        elif flag:
            self.installEventFilter(self._eventFilter)
        self._eventFilterEnabled = flag

    def plot(self, *args, **kwargs):
        plot = Plot()
        axes = PlotAxes(plot.viewport)
        axes.plot(*args, **kwargs)
        plot.addAxes(axes)
        return self.addPlot(plot)

    def adjustSelectRect(self, p0, p1):
        # can be used to restrict select rectangle, e.g. to given aspect ratio
        return p0, p1

    def paintEvent(self, event):
        super(InteractiveGRWidget, self).paintEvent(event)
        self._painter.begin(self)
        if self.getMouseSelectionEnabled() and self._tselect:
            p0, p1 = self._tselect
            coords = DeviceCoordConverter(self.dwidth, self.dheight)
            coords.setNDC(p0.x, p0.y)
            p0dc = coords.getDC()
            coords.setNDC(p1.x, p1.y)
            p1dc = coords.getDC()
            if self._getPlotsForPoint(p0):
                rect = QtCore.QRect(QtCore.QPoint(p0dc.x, p0dc.y),
                                    QtCore.QPoint(p1dc.x, p1dc.y)).normalized()
                self._painter.setOpacity(.75)
                self._painter.drawRect(rect)
                self._painter.setOpacity(1.)

        self._painter.end()

    def setAutoScale(self, mask):
        for plot in self._lstPlot:
            plot.autoscale = mask

    def getPickMode(self):
        return self._pickMode

    def setPickMode(self, bool):
        self._pickMode = bool
        self.modePick.emit(self._pickMode)

    def getMouseSelectionEnabled(self):
        return self._selectEnabled

    def setMouseSelectionEnabled(self, flag):
        self._selectEnabled = flag

    def getMousePanEnabled(self):
        return self._panEnabled

    def setMousePanEnabled(self, flag):
        self._panEnabled = flag

    def getMouseZoomEnabled(self):
        return self._zoomEnabled

    def setMouseZoomEnabled(self, flag):
        self._zoomEnabled = flag

    def _getPlotsForPoint(self, p0):
        res = []
        for plot in self._lstPlot:
            xmin, xmax, ymin, ymax = plot.viewportscaled
            if p0.x >= xmin and p0.x <= xmax and p0.y >= ymin and p0.y <= ymax:
                res.append(plot)
        return res

    def _pick(self, p0, type):
        for plot in self._getPlotsForPoint(p0):
            (coord, axes, _curve) = plot.pick(p0, self.dwidth, self.dheight)
            if coord:
                dcPoint = coord.getDC()
                QApplication.sendEvent(self, PickEvent(type,
                                                             self.dwidth,
                                                             self.dheight,
                                                             dcPoint.x,
                                                             dcPoint.y,
                                                             plot.viewport,
                                                             coord.getWindow(),
                                                             sizex=axes.sizex,
                                                             sizey=axes.sizey))

    def _select(self, p0, p1):
        self._pickEvent = None
        change = False
        for plot in self._getPlotsForPoint(p0):
            plot.select(p0, p1, self.dwidth, self.dheight)
            change = True
        if change:
            self.update()

    def mouseSelect(self, event):
        p0 = event.getNDC()
        p0, p1 = self.adjustSelectRect(p0, p0 + event.getOffset())
        self._tselect = (p0, p1)
        if event.isFinished():
            self._tselect = None
            self._select(p0, p1)
        self.update()

    def _mouseSelect(self, event):
        if self.getMouseSelectionEnabled():
            self.mouseSelect(event)

    def _pan(self, p0, dp):
        self._pickEvent = None
        change = False
        for plot in self._getPlotsForPoint(p0):
            plot.pan(dp, self.dwidth, self.dheight)
            change = True
        if change:
            self.update()

    def mousePan(self, event):
        self._pan(event.getNDC(), event.getOffset())

    def _mousePan(self, event):
        if self.getMousePanEnabled():
            self.mousePan(event)
            # disable roi recognition during pannning
            self._roiEnabled = event.isFinished()

    def _zoom(self, dpercent, p0):
        self._pickEvent = None
        change = False
        for plot in self._getPlotsForPoint(p0):
            plot.zoom(dpercent, p0, self.dwidth, self.dheight)
            change = True
        if change:
            self.update()

    def _roi(self, p0, type, buttons, modifiers):
        if self._roiEnabled:
            for plot in self._lstPlot:
                roi = plot.getROI(p0)
                if roi:
                    if roi.regionType == RegionOfInterest.LEGEND:
                        eventObj = LegendEvent
                    else:
                        eventObj = ROIEvent
                    coords = DeviceCoordConverter(self.dwidth, self.dheight)
                    coords.setNDC(p0.x, p0.y)
                    p0dc = coords.getDC()
                    QApplication.sendEvent(self,
                                                 eventObj(type,
                                                          self.dwidth,
                                                          self.dheight,
                                                          p0dc.x, p0dc.y,
                                                          buttons, modifiers,
                                                          roi))

    def mousePress(self, event):
        if event.getButtons() & MouseEvent.LEFT_BUTTON:
            if self.getPickMode():
                self.setPickMode(False)
                self._pick(event.getNDC(), PickEvent.PICK_PRESS)
            else:
                if event.getModifiers() & MouseEvent.CONTROL_MODIFIER:
                    self.setPickMode(True)

    def mouseRelease(self, event):
        self._roi(event.getNDC(), ROIEvent.ROI_CLICKED, event.getButtons(),
                  event.getModifiers())

    def mouseMove(self, event):
        if self.getPickMode():
            self._pick(event.getNDC(), PickEvent.PICK_MOVE)
        self._roi(event.getNDC(), ROIEvent.ROI_OVER, event.getButtons(),
                  event.getModifiers())

    def wheelMove(self, event):
        if self.getMouseZoomEnabled():
            # delta percent
            dpercent = event.getSteps() * .1
            self._zoom(dpercent, event.getNDC())

    def pickMove(self, event):
        self._pickEvent = event
        self.update()
示例#2
0
文件: __init__.py 项目: faroit/gr
class InteractiveGRWidget(GRWidget):

    logXinDomain = QtCore.Signal(bool)
    logYinDomain = QtCore.Signal(bool)
    modePick = QtCore.Signal(bool)

    def __init__(self, *args, **kwargs):
        super(InteractiveGRWidget, self).__init__(*args, **kwargs)
        guiConn = GUIConnector(self)
        guiConn.connect(qtgr.events.MouseEvent.MOUSE_MOVE, self.mouseMove)
        guiConn.connect(qtgr.events.MouseEvent.MOUSE_PRESS, self.mousePress)
        guiConn.connect(qtgr.events.MouseEvent.MOUSE_RELEASE,
                        self.mouseRelease)
        guiConn.connect(qtgr.events.WheelEvent.WHEEL_MOVE, self.wheelMove)
        guiConn.connect(qtgr.events.PickEvent.PICK_MOVE, self.pickMove)
        self.setMouseTracking(True)
        self._mouseLeft = False
        self._mouseRight = False
        self._startPoint = None
        self._curPoint = None
        self._logXinDomain = None
        self._logYinDomain = None
        self._pickMode = False
        self._pickEvent = None
        self._selectEnabled, self._panEnabled = True, True
        self._zoomEnabled = True
        self._lstPlot = []

    def draw(self, clear=False, update=True):
        if clear:
            gr.clearws()
        gr.setwsviewport(0, self.mwidth, 0, self.mheight)
        gr.setwswindow(0, self.sizex, 0, self.sizey)

        for plot in self._lstPlot:
            plot.sizex, plot.sizey = self.sizex, self.sizey
            plot.drawGR()
            # logDomainCheck
            logXinDomain = plot.logXinDomain()
            logYinDomain = plot.logYinDomain()
            if logXinDomain != self._logXinDomain:
                self._logXinDomain = logXinDomain
                self.logXinDomain.emit(self._logXinDomain)
            if logYinDomain != self._logYinDomain:
                self._logYinDomain = logYinDomain
                self.logYinDomain.emit(self._logYinDomain)

        if self._pickEvent:
            event = self._pickEvent
            gr.setviewport(*event.viewport)
            wcPoint = event.getWC(event.viewport)
            window = gr.inqwindow()
            gr.setwindow(*event.getWindow())
            gr.setmarkertype(gr.MARKERTYPE_PLUS)
            gr.polymarker([wcPoint.x], [wcPoint.y])
            gr.setwindow(*window)

    def addPlot(self, *args, **kwargs):
        for plot in args:
            if plot and plot not in self._lstPlot:
                self._lstPlot.append(plot)
        self._draw(clear=True, update=True)
        return self._lstPlot

    def plot(self, *args, **kwargs):
        plot = Plot()
        axes = PlotAxes(plot.viewport)
        axes.plot(*args, **kwargs)
        plot.addAxes(axes)
        return self.addPlot(plot)

    def adjustSelectRect(self, p0, p1):
        # can be used to restrict select rectangle, e.g. to given aspect ratio
        return p0, p1

    def paintEvent(self, event):
        super(InteractiveGRWidget, self).paintEvent(event)
        self._painter.begin(self)
        if self._mouseLeft and self.getMouseSelectionEnabled():
            p0 = self._startPoint.getNDC()
            p1 = self._curPoint.getNDC()
            p0, p1 = self.adjustSelectRect(p0, p1)
            coords = DeviceCoordConverter(self.dwidth, self.dheight)
            coords.setNDC(p0.x, p0.y)
            p0dc = coords.getDC()
            coords.setNDC(p1.x, p1.y)
            p1dc = coords.getDC()
            if self._getPlotsForPoint(p0):
                rect = QtCore.QRect(QtCore.QPoint(p0dc.x, p0dc.y),
                                    QtCore.QPoint(p1dc.x,
                                                  p1dc.y)).normalized()
                self._painter.setOpacity(.75)
                self._painter.drawRect(rect)
                self._painter.setOpacity(1.)

        self._painter.end()

    def setAutoScale(self, mask):
        for plot in self._lstPlot:
            plot.autoscale = mask

    def getPickMode(self):
        return self._pickMode

    def setPickMode(self, bool):
        self._pickMode = bool
        self.modePick.emit(self._pickMode)

    def getMouseSelectionEnabled(self):
        return self._selectEnabled

    def setMouseSelectionEnabled(self, flag):
        self._selectEnabled = flag

    def getMousePanEnabled(self):
        return self._panEnabled

    def setMousePanEnabled(self, flag):
        self._panEnabled = flag

    def getMouseZoomEnabled(self):
        return self._zoomEnabled

    def setMouseZoomEnabled(self, flag):
        self._zoomEnabled = flag

    def _getPlotsForPoint(self, p0):
        res = []
        for plot in self._lstPlot:
            xmin, xmax, ymin, ymax = plot.viewportscaled
            if p0.x >= xmin and p0.x <= xmax and p0.y >= ymin and p0.y <= ymax:
                res.append(plot)
        return res

    def _pick(self, p0, type):
        for plot in self._getPlotsForPoint(p0):
            (coord, _axes, _curve) = plot.pick(p0, self.dwidth, self.dheight)
            if coord:
                dcPoint = coord.getDC()
                QtGui.QApplication.sendEvent(
                    self,
                    PickEvent(type, self.dwidth, self.dheight, dcPoint.x,
                              dcPoint.y, plot.viewport, coord.getWindow()))

    def _select(self, p0, p1):
        self._pickEvent = None
        change = False
        for plot in self._getPlotsForPoint(p0):
            plot.select(p0, p1, self.dwidth, self.dheight)
            change = True
        if change:
            self._draw(True)
            self.update()

    def _pan(self, p0, dp):
        self._pickEvent = None
        change = False
        for plot in self._getPlotsForPoint(p0):
            plot.pan(dp, self.dwidth, self.dheight)
            change = True
        if change:
            self._draw(True)
            self.update()

    def _zoom(self, dpercent, p0):
        self._pickEvent = None
        change = False
        for plot in self._getPlotsForPoint(p0):
            plot.zoom(dpercent, p0, self.dwidth, self.dheight)
            change = True
        if change:
            self._draw(True)
            self.update()

    def _roi(self, p0, type, buttons, modifiers):
        for plot in self._lstPlot:
            roi = plot.getROI(p0)
            if roi:
                if roi.regionType == RegionOfInterest.LEGEND:
                    eventObj = LegendEvent
                else:
                    eventObj = ROIEvent
                coords = DeviceCoordConverter(self.dwidth, self.dheight)
                coords.setNDC(p0.x, p0.y)
                p0dc = coords.getDC()
                QtGui.QApplication.sendEvent(
                    self,
                    eventObj(type, self.dwidth, self.dheight, p0dc.x, p0dc.y,
                             buttons, modifiers, roi))

    def mousePress(self, event):
        if event.getButtons() & MouseEvent.LEFT_BUTTON:
            if self.getPickMode():
                self.setPickMode(False)
                self._pick(event.getNDC(), PickEvent.PICK_PRESS)
            else:
                if event.getModifiers() & MouseEvent.CONTROL_MODIFIER:
                    self.setPickMode(True)
                else:
                    self._mouseLeft = True
        elif event.getButtons() & MouseEvent.RIGHT_BUTTON:
            self._mouseRight = True
        self._curPoint = event
        self._startPoint = event

    def mouseRelease(self, event):
        if event.getButtons() & MouseEvent.LEFT_BUTTON and self._mouseLeft:
            self._mouseLeft = False
            self._curPoint = event
            p0 = self._startPoint.getNDC()
            p1 = self._curPoint.getNDC()
            if p0 != p1:
                if (self.getMouseSelectionEnabled()
                        and self._getPlotsForPoint(p0)):
                    p0, p1 = self.adjustSelectRect(p0, p1)
                    self._select(p0, p1)
            else:
                self._roi(p0, ROIEvent.ROI_CLICKED, event.getButtons(),
                          event.getModifiers())
        elif event.getButtons() & MouseEvent.RIGHT_BUTTON and self._mouseRight:
            self._mouseRight = False
            self._roi(event.getNDC(), ROIEvent.ROI_CLICKED, event.getButtons(),
                      event.getModifiers())
        self._curPoint = event

    def mouseMove(self, event):
        if self.getPickMode():
            self._pick(event.getNDC(), PickEvent.PICK_MOVE)
        if event.getButtons() & MouseEvent.LEFT_BUTTON:
            self._curPoint = event
            super(InteractiveGRWidget, self).update()
        elif event.getButtons() & MouseEvent.RIGHT_BUTTON:
            p0 = self._curPoint.getNDC()  # point before now
            p1 = event.getNDC()
            dp = p1 - p0
            self._curPoint = event
            if self.getMousePanEnabled():
                self._pan(self._startPoint.getNDC(), dp)
                self._mouseRight = False
        self._roi(event.getNDC(), ROIEvent.ROI_OVER, event.getButtons(),
                  event.getModifiers())

    def wheelMove(self, event):
        if self.getMouseZoomEnabled():
            # delta percent
            dpercent = event.getSteps() * .1
            self._zoom(dpercent, event.getNDC())

    def pickMove(self, event):
        self._pickEvent = event
        self.update()