查科圆覆盖

2024-06-25 22:56:36 发布

您现在位置:Python中文网/ 问答频道 /正文

我想用Chaco创建一个圆覆盖工具,它是BetterSelectingZoom的一个更简单的版本:left down设置圆的中心,拖动left down绘制圆,left up丢弃圆。不幸的是,我不能很好地理解代码_缩放.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()

Tags: fromimportselfeventplotdefnpleft