chaco圆形覆盖工具

时间:2015-01-07 04:17:42

标签: python chaco

我想用Chaco创建一个圆形叠加工具,这是BetterSelectingZoom的一个更简单的版本:左下设置圆心,左下拖动绘制圆,左上放弃圆。不幸的是,我不能完全遵循better_selecting_zoom.py中的代码;特别是,我不太了解如何动态添加,删除或修改叠加圈。下面是CircleTool类的尝试。任何人都可以朝着正确的方向推动我吗?

import sys
import numpy as np
from traits.api import HasTraits, Instance
from traits.api import Bool, Tuple, Float
from traitsui.api import View, Item
from enable.api import Component, ComponentEditor
from chaco.api import Plot, ArrayPlotData
from chaco.api import AbstractOverlay, BaseTool

class CircleTool(AbstractOverlay,BaseTool):
    '''
    provides dynamic circle overlay on a plot: left down sets circle center,
    left down drag draws circle, left up removes circle overlay.
    '''

    _select_on = Bool(False) 
    _select_center = Tuple((0,0))
    _select_radius = Float(0)

    def __init__(self,component=None,**kwargs):
        '''
        initialize CircleTool as an overlay and a tool
        '''
        AbstractOverlay.__init__(self,component=component,**kwargs)
        BaseTool.__init__(self,component=component,**kwargs)

    def normal_left_down(self,event):
        '''
        set selection flag to True; save circle center; CircleTool to the
        overlays list of component (plot); discard event.
        '''
        self._select_on = True
        self._select_center = (event.x,event.y)
        self.component.overlays.append(self)        
        event.handled = True

    def normal_left_up(self,event):
        '''
        set selection flag to False; get index of the CircleTool overlay in 
        component's overlays list; discard CircleTool overlay; redraw plot;
        discard event.
        '''
        self._select_on = False
        ixself = self.component.overlays.index(self)
        self.component.overlays.pop(ixself)
        self.component.request_redraw()
        event.handled = True        

    def normal_mouse_move(self,event):
        '''
        if selection flag is True, get circle centre and current point;
        compute radius (coordinates and radius units are screen pixels.)
        demand redraw of plot which calls self.overlay()
        '''
        if not self._select_on: return
        xc, yc = self._select_center
        xp, yp = (event.x,event.y)
        self._select_radius = float(np.sqrt((xc-xp)**2 + (yc-yp)**2))
        self.component.request_redraw()

    def overlay(self,component,gc,view_bounds=None,mode='normal'):
        '''
        draw gc (Kiva Graphics Context System object) on component; define
        gc as a circle.  
        ??? in Chaco code, with gc is used.  Why?
        '''
        gc.set_line_width(2)
        gc.set_stroke_color((0,0,0))
        gc.clip_to_rect(component.x, component.y, component.width, component.height)
        gc.arc(self._select_center[0],self._select_center[1],self._select_radius,0,2*np.pi)
        gc.stroke_path()

class CircleOverlay(AbstractOverlay):
    '''
    basic test overlay: red circle at (200,300) with radius 50.
    '''
    def overlay(self,component,gc,view_bounds=False,mode='normal'):
        gc.set_stroke_color((1,0,0))
        gc.set_line_width(2)
        gc.arc(200,300,50,0,2*np.pi)
        gc.stroke_path()


class PlotExample(HasTraits):
    plot = Instance(Component)
    traits_view = View(Item('plot',editor=ComponentEditor()),
                       width=500,height=500,resizable=True,
                       title='TEST-CIRCLE-TOOL')

    def __init__(self,*args,**kwargs):
        super(PlotExample,self).__init__(*args,**kwargs)
        # create plot
        x = np.linspace(0,2*np.pi,100)
        y = np.sin(x)
        plotData = ArrayPlotData(x=x,y=y)
        plot = Plot(plotData)
        plot.plot(('x','y'),type='line')

        # append circle tool
        circleTool = CircleTool(component=plot)
        plot.tools.append(circleTool)

        # append circle overlay
        circleOverlay = CircleOverlay(component=plot)
        plot.overlays.append(circleOverlay)

        # save plot for later
        self.plot = plot

if __name__ == '__main__':
    plotExample = PlotExample()
    plotExample.configure_traits()

0 个答案:

没有答案