0

我需要定义 2 个在同一时间和同一区域移动的矩形选择器,当我相互移动同时移动时,我该怎么做?

这是一个简单的代码,在 2 个面板和 2 个矩形中有 2 个绘图

可以使两个矩形同时移动,因为我在网络或 matplotlib 中没有找到任何示例

我将 wxpython 4 用于 python3.6

import wx
from numpy import arange, sin, pi,cos
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.widgets import RectangleSelector
from matplotlib.figure import Figure



class MainFrame(wx.Frame):
    def __init__(self, parent ):
        wx.Panel.__init__(self, parent,name="Main", size = (600,800))
        Top = PanelTop(self)
        Bottom = PanelBottom(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(Top, 1, wx.EXPAND)
        sizer.Add(Bottom, 1, wx.EXPAND)
        self.SetSizer(sizer)


class PanelTop(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size = (300,300))
        self.SetBackgroundColour('white')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)


        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)



    def line_select_callback(self, eclick, erelease):
         x1, y1 = eclick.xdata, eclick.ydata
         x2, y2 = erelease.xdata, erelease.ydata


class PanelBottom(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self, parent, size = (300,300))
        self.SetBackgroundColour('grey77')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)

        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)



    def line_select_callback(self, eclick, erelease):
         x1, y1 = eclick.xdata, eclick.ydata
         x2, y2 = erelease.xdata, erelease.ydata



app = wx.App()
frame = MainFrame(None).Show()
app.MainLoop()

先感谢您

4

1 回答 1

1

我不知道这是否应该这样做,但这是一种方法。
我已经在适当的地方注释了代码。
该方法只是简单地抓取第一个 Rectangle 的坐标,强制它们进入第二个,然后重新绘制它。
第二个矩形被设为and不活动,因为如果它不是不活动的,它意味着它是第一个矩形的从属,角落和中间的控制点无法随矩形移动。这让我相信,可能有一种不那么老套的方法来实现相同的结果。

import wx
from numpy import arange, sin, pi,cos
import numpy as np
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.widgets import RectangleSelector
from matplotlib.figure import Figure

class MainFrame(wx.Frame):
    def __init__(self, parent ):
        wx.Panel.__init__(self, parent,name="Main", size = (600,800))
        self.Top = PanelTop(self)
        self.Bottom = PanelBottom(self)
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(self.Top, 1, wx.EXPAND)
        sizer.Add(self.Bottom, 1, wx.EXPAND)
        self.SetSizer(sizer)

class PanelTop(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent,size = (300,300))
        self.SetBackgroundColour('white')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)


        t = arange(0.5, 3.0, 0.01)
        s = cos(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=True, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)

    def line_select_callback(self, eclick, erelease):
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        rect = self.RS.artists[0] # Rectangle artist
        slave_rect = self.Parent.Bottom.RS.artists[0] # Rectangle artist
        slave_canvas = self.Parent.Bottom.canvas

        # Force new positional values into slave rectangle
        slave_rect.set_x(x1)
        slave_rect.set_y(y1)
        slave_rect.set_width(x2-x1)
        slave_rect.set_height(y2-y1)
        slave_rect.update(dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        #Force visible in case slave rectangle has been clicked on
        slave_rect.set_visible(True)
        #Redraw slave rectangle
        slave_canvas.draw()

class PanelBottom(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self, parent, size = (300,300))
        self.SetBackgroundColour('grey77')
        self.figure = Figure(figsize = (4,5))
        self.axes = self.figure.add_subplot(111)
        self.canvas = FigureCanvas(self,-1,self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.GROW)
        self.SetSizer(self.sizer)

        t = arange(0.0, 3.0, 0.01)
        s = sin(2 * pi * t)
        self.axes.plot(t, s)
        self.RS = RectangleSelector(self.axes,self.line_select_callback,
                                       drawtype='box', useblit=False,
                                       button=[1, 3],minspanx=1, minspany=1,
                                       spancoords='pixels',
                                       interactive=False, rectprops = dict(facecolor='None',edgecolor='red',alpha=5,fill=False))
        self.RS.to_draw.set_visible(True)
        self.RS.extents = (1,0,0,1)

    def line_select_callback(self, eclick, erelease):
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata

app = wx.App()
frame = MainFrame(None).Show()
app.MainLoop()
于 2019-05-16T17:02:08.147 回答