从Tkinter画布中删除补丁并单击列表

时间:2016-06-14 15:23:20

标签: python tkinter tkinter-canvas

我正在制作一个GUI(到目前为止)可以在图形上绘制多个矩形,检索这些矩形的坐标,然后将这些坐标写入可以保存为.txt文件的列表。 我希望能够删除我不需要的任何矩形,并从图中和list / txt文件中删除它们。到目前为止,我能够删除最后绘制的补丁(仅从图中删除它,而不是列表),但是当我再次点击时我得到错误:

Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py", line 1536, in __call__
    return self.func(*args)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/backends/backend_tkagg.py", line 395, in button_press_event
    FigureCanvasBase.button_press_event(self, x, y, num, dblclick=dblclick, guiEvent=event)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/backend_bases.py", line 1785, in button_press_event
    self.callbacks.process(s, mouseevent)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/cbook.py", line 527, in process
    proxy(*args, **kwargs)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/cbook.py", line 405, in __call__
    return mtd(*args, **kwargs)
  File "stack_overflowquestion.py", line 115, in delete_click
    self.rect.remove()
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/artist.py", line 135, in remove
    self._remove_method(self)
  File "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/axes.py", line 1564, in <lambda>
    p._remove_method = lambda h: self.patches.remove(h)
ValueError: list.remove(x): x not in list

我希望能够点击任何矩形并将其删除,而不是按照绘制顺序删除它们。我想这意味着我需要在创建矩形时以某种方式命名/索引矩形。

我的代码:

import numpy as np
import matplotlib
matplotlib.use('TkAgg')
from matplotlib.figure import *
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
import matplotlib.pyplot as plt
from matplotlib import gridspec
from matplotlib.ticker import MultipleLocator, FormatStrFormatter

import tkFileDialog 
import tkMessageBox
import Tkinter as tk

from matplotlib.patches import Rectangle

Area = []
class simpleapp_tk(tk.Tk):
    def __init__(self, parent):
        tk.Tk.__init__(self, parent)
        self.parent=parent
        self.initialize()

    def initialize(self):       
        button = tk.Button(self, text="Plot data", command=self.plot)
        button.pack()   
        button = tk.Button(self, text="Quit", command=self.quit)
        button.pack()   
        button = tk.Button(self, text="Save file", command=self.save)
        button.pack()   

        self.labelVariable = tk.StringVar()
        self.var = tk.IntVar()
        label = tk.Label(self, textvariable=self.labelVariable, anchor = "w", fg = 'white', bg = 'blue')
        label.pack()
        self.labelVariable.set("Data Browser")
        self.resizable(True, True) 

    def plot (self):
        try:
            self.fig = plt.figure('Input para+perp ATB')
            gs  = gridspec.GridSpec(4, 6)
            self.ax1 = self.fig.add_subplot(gs[0:4, 0:5])
            im  = self.ax1.plot([1, 2, 3, 4, 5, 6, 7], [2, 4, 6, 8, 9, 11, 12])
            canvas = FigureCanvasTkAgg(self.fig, master=self)
            canvas.show()
            canvas.get_tk_widget().pack()

            toolbar = NavigationToolbar2TkAgg(canvas, self)
            toolbar.update()
            canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
            aid = self.fig.canvas.mpl_connect('button_press_event', self.on_press)
            bid = self.fig.canvas.mpl_connect('button_release_event', self.on_release)
            cid = self.fig.canvas.mpl_connect('motion_notify_event', self.on_motion)
            did = self.fig.canvas.mpl_connect('button_press_event', self.delete_click)

            Radio1 = tk.Radiobutton(text = 'Select areas', variable = self.var, indicatoron=0, value = 1)
            Radio2 = tk.Radiobutton(text = 'Delete areas', variable = self.var, indicatoron=0, value = 2)
            Radio1.pack()
            Radio2.pack()

        except SyntaxError:   
            tkMessageBox.showinfo("No file selected", "Please select a file")

    def on_press(self, event):
        self.is_pressed = True
        if event.xdata is not None and event.ydata is not None:
            if self.var.get() ==1:
                self.rect = Rectangle((0, 0), 0, 0)
                self.ax1.add_patch(self.rect)
                self.x0, self.y0 = event.xdata, event.ydata
                self.rect.set_width(0)
                self.rect.set_height(0)
                self.rect.set_xy((self.x0, self.y0))
                self.fig.canvas.draw()
                self.rect.set_edgecolor('red')
                self.rect.set_linestyle('solid')
                self.rect.set_facecolor('none')
                self.rect.set_linewidth('5')

    def on_motion(self, event):
        try:
            if self.is_pressed:
                if event.xdata is not None and event.ydata is not None:
                    if self.var.get() ==1:
                        self.x1, self.y1 = event.xdata, event.ydata
                        self.rect.set_width(self.x1 - self.x0)
                        self.rect.set_height(self.y1 - self.y0)
                        self.rect.set_xy((self.x0, self.y0))
                        self.fig.canvas.draw()
        except SyntaxError:
            pass 

    def on_release(self, event):
        self.is_pressed = False
        if self.var.get() ==1:
            self.x1, self.y1 = event.xdata, event.ydata
            self.rect.set_xy((self.x0, self.y0))

            print 'rect:', self.x0, self.y0, self.x1, self.y1
            coords =([self.x0, self.y0, self.x1, self.y1])
            Area.append(coords)

        self.fig.canvas.draw()

    def delete_click(self, event):
        self.is_pressed = True
        if self.var.get() ==2:
            self.rect.remove()

    def save(self):
        file = tkFileDialog.asksaveasfile(mode ='w', defaultextension=".txt")
        if file is None:
            return
        savewhat = Area
        for item in Area:
            file.write("%s\n" % item)
        file.close() 

def quit():
    root.destroy()

if __name__ == "__main__":
    app = simpleapp_tk(None)
    app.title('Data Browser')
    app.mainloop()

0 个答案:

没有答案
相关问题