首页 > 解决方案 > 附加使用交互模式和用户输入的python类?

问题描述

我有一个类允许用户使用鼠标创建一个区域。现在我想通过将对象附加到列表来创建多个区域。

但是,当我尝试附加它时,它只运行一次,我得到了同一区域的 2 个副本。似乎两者同时并行运行。这个问题有简单的解决方法吗?

import numpy as np
import sys
import matplotlib.pyplot as plt
import matplotlib.path as mplPath
import matplotlib.image as mpimg

class create_region():

def __init__(self, img):
    if isinstance(img, np.ndarray):
         plt.imshow(img)
         fig = plt.gcf()
         fig.set_size_inches(12,9)
    else:
         print('Error: please include an image np.ndarray, create_region(img)')
         return

    self.img = img
    self.img_size = np.shape(img)
    self.line = None
    self.roicolor = (.415,1,.302) # Use neon green to stand out
    self.markersize = 4

    self.x_pts = []
    self.y_pts = []
    self.previous_pt = []
    self.start_point = []
    self.end_point = []
    self.fig = fig
    self.ax = plt.gca()

    self.__ID1 = self.fig.canvas.mpl_connect(
        'motion_notify_event', self.__motion_notify_callback)
    self.__ID2 = self.fig.canvas.mpl_connect(
        'button_press_event', self.__button_press_callback)

    if sys.flags.interactive:
        plt.show(block=False)
    else:
        plt.show()

def __motion_notify_callback(self, event):
    if event.inaxes:
        #ax = event.inaxes
        x, y = event.xdata, event.ydata
        # Move line around
        if (event.button == None or event.button == 1) and self.line != None: 
            self.line.set_data([self.previous_pt[0], x],
                               [self.previous_pt[1], y])
            self.fig.canvas.draw()

def __button_press_callback(self, event):
    if event.inaxes:
        x, y = event.xdata, event.ydata
        ax = event.inaxes
        # If you press the left button, single click
        if event.button == 1 and event.dblclick == False:  
            if self.line == None: # if there is no line, create a line
                self.line = plt.Line2D([x, x],
                                       [y, y],
                                       marker='o',
                                       color=self.roicolor,
                                       markersize = self.markersize)
                self.start_point = [x,y]
                self.previous_pt =  self.start_point
                self.x_pts=[x]
                self.y_pts=[y]

                ax.add_line(self.line)
                self.fig.canvas.draw()
                # add a segment
            else: # if there is a line, create a segment
                self.line = plt.Line2D([self.previous_pt[0], x],
                                       [self.previous_pt[1], y],
                                       marker = 'o',color=self.roicolor,
                                       markersize = self.markersize)
                self.previous_pt = [x,y]
                self.x_pts.append(x)
                self.y_pts.append(y)

                event.inaxes.add_line(self.line)
                self.fig.canvas.draw()
        # close the loop and disconnect
        elif ((event.button == 1 and event.dblclick==True) or
              (event.button == 3 and event.dblclick==False)) and self.line != None: 
            self.fig.canvas.mpl_disconnect(self.__ID1) #joerg
            self.fig.canvas.mpl_disconnect(self.__ID2) #joerg

            self.line.set_data([self.previous_pt[0],
                                self.start_point[0]],
                               [self.previous_pt[1],
                                self.start_point[1]])
            ax.add_line(self.line)
            self.fig.canvas.draw()
            self.line = None

            if sys.flags.interactive:
                pass
            else:
                #figure has to be closed so that code can continue
                plt.close(self.fig) 

# create zeros image
img=np.zeros((768,1024),dtype='uint8')

# try to append 2 different user regions to list
# seems both run simultaneously, returns 2 copies of 1 region   
M = []
for i in range(2):
    M.append(create_region(img))

标签: pythonpython-interactive

解决方案


推荐阅读