在wxPython面板中加载新图像时,Matplotlib矩形选择器将消失

在wxPython面板中加载新图像时,Matplotlib矩形选择器将消失,python,matplotlib,wxpython,matplotlib-widget,Python,Matplotlib,Wxpython,Matplotlib Widget,我在wxPython面板中有一个图像,我想通过使用MatplotlibRectangleSelector进行选择来编辑该图像。我有一个绘制图像的Image\u查看器类。我有一个编辑器类,其中包含矩形选择器功能编辑器继承自图像查看器。最后,一个控制面板将保存文件选择器按钮。程序从通过图像查看器绘图功能加载的默认图像开始。我可以使用矩形选择器很好。但是当我加载一个新图像时,它也通过image\u Viewerdraw函数加载,与RectangleSelector的所有连接都会消失 我试图尽可能减少代

我在wxPython面板中有一个图像,我想通过使用Matplotlib
RectangleSelector
进行选择来编辑该图像。我有一个绘制图像的
Image\u查看器
类。我有一个
编辑器
类,其中包含
矩形选择器
功能<代码>编辑器继承自
图像查看器
。最后,一个控制面板将保存文件选择器按钮。程序从通过
图像查看器
绘图功能加载的默认图像开始。我可以使用
矩形选择器
很好。但是当我加载一个新图像时,它也通过
image\u Viewer
draw函数加载,与
RectangleSelector
的所有连接都会消失

我试图尽可能减少代码,但整个过程都是多选项卡笔记本的一部分,因此出现了
wx.lib.agw.aui
和其他可能的特性

import os
import cv2 as cv
import matplotlib.pyplot as plt
import numpy as np
import wx
import wx.lib.agw.aui as aui
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.widgets import RectangleSelector
from matplotlib.patches import Rectangle

# ------------------variables-------------------
# Base path
pth = os.path.dirname(os.path.abspath('__file__'))
# folder for gui graphics
gui_graphics = pth + '/gui_graphics'
# temp file for initial image handling
img_pth = os.path.join(pth, "tmp_img.png")
# Folders, subfolders for processed images
all_cats = pth + '/Cats'
new_cats = all_cats + '/new_cats'

min_img_wndw = 295      # min size of top panels
img_y, img_x = 64, 64   # raw cat size

class Image_Viewer(wx.Panel):
    def __init__(self, parent):
        super(Image_Viewer, self).__init__(parent)
        #load image
        im_pth = new_cats + '/av_cat'
        files = os.listdir(im_pth)
        im_pths = [os.path.join(im_pth, im_name) for im_name in files]
        try:
            self.img = max(im_pths, key=os.path.getctime)
            self.image = cv.imread(self.img)
        except:
            self.image = np.zeros((img_x, img_y), np.uint8)

        self.figure = Figure()
        self.draw(self.image)

    def draw(self, image):
        plt.close(self.figure)
        self.figure.clf()
        self.axes = self.figure.add_axes([0, 0, 1, 1])
        self.axes.axis('off')
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
        self.axes.imshow(image, cmap='gray', vmin=0, vmax=255)
        self.canvas.draw()

class Editor(Image_Viewer):
    def __init__(self, parent):
        super(Editor, self).__init__(parent)

        self.RS = RectangleSelector(self.axes, self.on_click,
                                    drawtype='box', useblit=True,
                                    button=[1, 3],  # don't use middle button
                                    minspanx=5, minspany=5,
                                    spancoords='pixels',
                                    interactive=True)
        #self.canvas.draw()
        cid = self.canvas.mpl_connect('MouseEvent', self.on_click)
        print(cid)

    def on_click(self, eclick, erelease):
        print("You clicked")
        'eclick and erelease are the press and release events'
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        w = int(x2-x1)
        h = int(y2 - y1)

class control_Panel(wx.Panel):
    def __init__(self, parent, image_panel):     #, image_panel, terminal_panel
        wx.Panel.__init__(self, parent=parent)
        #self.panel = wx.Panel(self, -1, size=(580, 180))
        self.screen = image_panel

        self.pth = os.path.dirname(os.path.abspath('__file__'))
        fileDlgBtn = wx.Button(self, label="Get Cats")
        fileDlgBtn.Bind(wx.EVT_BUTTON, self.OnOpen)

    def OnOpen(self, event):
        with wx.FileDialog(self, "Open image file", wildcard="PNG files (*.png)|*.png",
                           style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST) as fileDialog:

            if fileDialog.ShowModal() == wx.ID_CANCEL:
                return     # the user changed their mind

            # Proceed loading the file chosen by the user
            pathname = fileDialog.GetPath()
            image = cv.imread(pathname)
            self.screen.draw(image)

class explorer_panel(wx.Panel):
    def __init__(self, parent):
        """Constructor"""
        wx.Panel.__init__(self, parent)
        bSplitter = wx.SplitterWindow(self)
        image_panel = Editor(bSplitter)
        panelThree = control_Panel(bSplitter, image_panel)  

        bSplitter.SplitHorizontally(image_panel, panelThree)
        bSplitter.SetSashGravity(0.5)

        bSplitter.SetMinimumPaneSize(min_img_wndw)

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(bSplitter, 1, wx.EXPAND)
        self.SetSizer(sizer)

class Main(wx.Frame):
    def __init__(self):
        wx.Frame.__init__(
            self, 
            parent = None, 
            title = "Borges Infinite Image", 
            size = (600,550)
            )
        self.SetIcon(wx.Icon(gui_graphics + '/Abe.png'))

        panel = wx.Panel(self)
        notebook = aui.AuiNotebook(panel)
        explorer = explorer_panel(notebook)
        notebook.AddPage(explorer, 'Explorer')
        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(notebook, 1, wx.ALL|wx.EXPAND, 5)
        panel.SetSizer(sizer)

if __name__ == "__main__":
    app = wx.App()
    frame = Main()
    frame.Show()
    app.MainLoop()

我无法测试您的代码,因为我没有安装wx atm,但我很确定您的问题源于每次加载新图片时创建新图形和新画布

我相信你应该创建一个图形和一组轴,然后用新图片替换这些轴的内容

e、 g

class Image_Viewer(wx.Panel):
    def __init__(self, parent):
        (...)

        self.figure = Figure()
        self.axes = self.figure.add_axes([0, 0, 1, 1])
        self.axes.axis('off')
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.VERTICAL)
        self.sizer.Add(self.canvas, 1, wx.EXPAND)
        self.SetSizer(self.sizer)
        self.draw(self.image)

    def draw(self, image):
       self.axes.cla()
       self.axes.imshow(image, cmap='gray', vmin=0, vmax=255)
       self.canvas.draw()