2014-10-20 2 views
0

간단한 페인트 프로그램을 작성했으며 작업에 문제가 있습니다. 그려진 선을 삭제하거나 제거 할 수 있기를 원합니다. ButtonPress-1이 작동 중지되면 ButtonRelease-1이 트리거 될 때까지 (ButtonPress-1이 가동 중임) 라인을 작성합니다. 'Reset'버튼을 누르면 라인이 삭제/제거되기를 원합니다. 나는 현재 그것을 가지고 있기 때문에 'Reset'을 누르면 프로그램이 스스로 재시작한다. 이것은 나쁜 해결책이다.Python tkinter delete event.widget.create_line

from Tkinter import * 
import tkMessageBox 
import sys 
import os 
import subprocess 

b1 = "up" 
xold, yold = None, None 
color= "black" 
linesize = 2 

def main(): 
    global root 
    root = Tk() 
    global drawing_area 
    drawing_area = Canvas(root, width=1050, height=1200, background="white") 
    drawing_area.pack() 
    drawing_area.bind("<Motion>", motion) 
    drawing_area.bind("<ButtonPress-1>", b1down) 
    drawing_area.bind("<ButtonRelease-1>", b1up) 

    button1 = Button(root, text = "Reset", command = restart_program, anchor = N) 
    button1.configure(width = 3, background = "#FFFFFF", relief = FLAT) 
    button1_window = drawing_area.create_window(640, 0, anchor=N, window=button1) 

    root.geometry('1050x1200') 
    root.geometry('+0+720') 
    root.mainloop() 

def restart_program(): 
    python = sys.executable 
    os.execl(python, python, * sys.argv) 

def b1down(event): 
    global b1 
    b1 = "down" 

def b1up(event): 
    global b1, xold, yold 
    b1 = "up" 
    xold = None 
    yold = None 

def motion(event): 
    if b1 == "down": 
     global xold, yold 
     if xold is not None and yold is not None: 
      event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE,fill = color, width=linesize) 
     xold = event.x 
     yold = event.y 

if __name__ == "__main__": 
    main() 

답변

3

당신이 캔버스에 모든 항목을 삭제하려면 당신은
("모두") canvas.delete를 호출 할 수 있습니다 또는 당신은 태그 라인을 만들 수 있습니다 다음 태그에 의해 삭제

그래서 당신은 변경 될 수 있습니다 :

event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE,fill = color, width=linesize) 

에 :

event.widget.create_line(xold,yold,event.x,event.y,smooth=TRUE,fill = color, width=linesize, tag="line") 

및 다음을 호출하십시오 : canvas.delete ("line")

이렇게하면 해당 태그가있는 모든 항목이 삭제됩니다. 편집

: 여기에 망하는 요청에 더 간단한 실행 취소/기능을 다시 실행, 다음과 같은 단점에 유의 할 수있는 코드 예제입니다 : 당신은 저장 목록이 지속적으로 성장할 것 이상의 항목을 실행 취소로

  1. 를, 그것은이다 당신이 항목을 취소 한 후 다시 수동으로 새 항목을 그리면 어떤 집합 크기
  2. 에만 국한되지는 않습니다 여전히 제거 선을 다시 넣어

    import Tkinter as tk 
    import tkMessageBox 
    import sys 
    import os 
    
    class App(tk.Tk): 
        b1 = "up" 
        xold, yold = None, None 
        color= "black" 
        linesize = 2 
        counter = 1 #keeps track of the current working line, is incremented as soon as line is finished 
        undone = [] #keeps a list of coordinate lists on undone items 
    
        def __init__(self): 
         tk.Tk.__init__(self) 
         self.drawing_area = tk.Canvas(self, width=600, height=600, background="white") 
         self.drawing_area.pack() 
         self.drawing_area.bind("<Motion>", self.motion) 
         self.drawing_area.bind("<ButtonPress-1>", self.b1down) 
         self.drawing_area.bind("<ButtonRelease-1>", self.b1up) 
    
         self.button1 = tk.Button(self, text = "Reset", command = self.blank_canvas, anchor = tk.N) 
         self.button1.configure(width = 3, background = "#FFFFFF", relief = tk.FLAT) 
         self.button1.pack(side="left") 
    
         self.button2 = tk.Button(self, text = "Undo", command = self.undo, anchor = tk.N) 
         self.button2.configure(width = 3, background = "#FFFFFF", relief = tk.FLAT) 
         self.button2.pack(side="left") 
    
         self.button3 = tk.Button(self, text = "Redo", command = self.redo, anchor = tk.N) 
         self.button3.configure(width = 3, background = "#FFFFFF", relief = tk.FLAT) 
         self.button3.pack(side="left") 
    
        def blank_canvas(self): 
         self.drawing_area.delete("line") 
    
        def undo(self): 
         self.counter -= 1 #decrements the counter to look at the previous item 
         currentlist = [] #creates a list to store the coordinates in 
         for item in self.drawing_area.find_withtag("line"+str(self.counter)): #find all sub lines from the previous line 
          currentlist.append(self.drawing_area.coords(item)) #get and add the coordinates to the working list 
         self.drawing_area.delete("line"+str(self.counter)) #delete all items of the current line 
         self.undone.append(currentlist) #add the working list to the stored list 
    
        def redo(self): 
         try: 
          currentlist = self.undone.pop() #fetch and remove last set of coordinates 
          for coords in currentlist: #for set of coordinates redraw subline 
           self.drawing_area.create_line(coords,smooth=tk.TRUE,fill = self.color, width=self.linesize, tags=["line", "line"+str(self.counter)]) 
          self.counter += 1 #re increment counter 
         except IndexError: 
          pass #occurs if list is empty 
    
        def b1down(self, event): 
         self.b1 = "down" 
    
        def b1up(self, event): 
         self.b1 = "up" 
         self.xold = None 
         self.yold = None 
         self.counter += 1 
    
        def motion(self, event): 
         if self.b1 == "down": 
          if self.xold is not None and self.yold is not None: 
           event.widget.create_line(self.xold,self.yold,event.x,event.y,smooth=tk.TRUE,fill = self.color, width=self.linesize, tags=["line", "line"+str(self.counter)]) 
          self.xold = event.x 
          self.yold = event.y 
    
    if __name__ == "__main__": 
        app = App() 
        app.mainloop() 
    
+0

완벽하게 작동합니다. –

+0

안녕하세요. 이 프로그램에서도 실행 취소 및 다시 실행 기능을 만들려고합니다. 삭제를 위해 여기에서 사용한 것과 같은 방법을 시도했지만 작동하지 않습니다. 그것에 대해 많은 문서를 찾을 수 없습니다. 위와 같은 시도를했지만 canvas.edit_undo ("line") 'function'을 사용해 보았습니다. 당신은 tkinter에 대한 좋은 지식을 가지고있는 것 같습니다. 아마도 당신은 약간의 조언을 얻을 수 있습니다. 또한 답변 할 필요는 없지만 도움이 필요하거나 도움을 줄 수없는 경우 회신을 남겨주세요. –

+1

제 답변에 대한 수정 내용을 참조하십시오. –