python+;tkinter:如何将画布同时用于主功能和子功能?

python+;tkinter:如何将画布同时用于主功能和子功能?,python,tkinter,tkinter-canvas,Python,Tkinter,Tkinter Canvas,这应该是一个简单的问题,但我就是没有找到答案 我制作了一个主功能,其中绘制了一个按钮和一条线。我还有一个子功能,它连接到主功能中的按钮 通过单击按钮,我希望在同一窗口中绘制另一条线,原始线应该被删除 这是我写的代码。我真的不知道如何完成它。非常感谢您的任何帮助。谢谢 import Tkinter as tk def DrawFunc(): x1 = 20 ; y1 = 20 x2 = 60 ; y2 = 80 S_Canvas = tk.Canvas(root)

这应该是一个简单的问题,但我就是没有找到答案

我制作了一个主功能,其中绘制了一个按钮和一条线。我还有一个子功能,它连接到主功能中的按钮

通过单击按钮,我希望在同一窗口中绘制另一条线,原始线应该被删除

这是我写的代码。我真的不知道如何完成它。非常感谢您的任何帮助。谢谢

import Tkinter as tk

def DrawFunc():
    x1 = 20 ; y1 = 20
    x2 = 60 ; y2 = 80

    S_Canvas = tk.Canvas(root)
    S_Canvas.pack()

    S_Canvas.create_line(x1, y1, x2, y2, fill="black")  # When the button is clicked, this line should be shown. And the old line should be deleted.


def Window():
    global root
    root = tk.Tk()
    root.geometry("400x400")

    S_Canvas = tk.Canvas(root)
    S_Canvas.pack()
    S_Canvas.create_line(50, 250, 250, 70, fill="red")  # When the program is run, this line is shown.

    Frame_1 = tk.Frame(root)
    Frame_1.place(width=120, height=80, x=0, y=0)
    Button_1 = tk.Button(Frame_1, text = u"Draw", width = 20, height=10, bg= "green" ,command = DrawFunc())
    Button_1.pack()

    root.mainloop()
Window()

要在相同的
画布中绘制,您的
DrawFunc
函数必须知道该画布。 最快的解决方案是将
targetCanvas
参数添加到
DrawFunc
函数中,并将其传递给
S_Canvas
我可能记得不好,但我认为tkinter不支持直接向回调函数传递参数。作为解决方法,您可以使用lambda函数:

Button_1 = tk.Button(Frame_1,
                     text = u"Draw",
                     width = 20,
                     height=10,
                     bg= "green",
                     command = lambda: DrawFunc(targetCanvas))
但是,如果要重用此命令,必须定义一个不带参数的
draw\u func\u命令
函数:

def draw_func_command():
    global S_Canvas
    DrawFunc(S_Canvas)
但是,您需要将
S_Canvas
声明为全局… 为了避免这种情况,实现UI元素的一般方法是将它们声明为类。不过,我不打算在这里进一步阐述,因为这是一个广泛的话题,有点超出了问题的范围。

要删除第一行,有点棘手。实际上,
Canvas.create\u line
返回一个对象,即绘制的线。要删除它,必须将其存储在变量中,然后对其调用
delete
函数。

代码的问题是函数不在同一个类中,因此变量必须相互传递… 至于擦除画布问题,请在
DrawFunc
函数中添加一个
oldLine
参数,然后在函数体中调用
oldLine.delete()

currentLine = S_Canvas.create_line(50, 250, 250, 70, fill="red")

Button1=Button(…,command=lambda:DrawFunc(targetCanvas,currentLine))要在相同的
画布中绘制,您的
DrawFunc
函数必须知道该画布。 最快的解决方案是将
targetCanvas
参数添加到
DrawFunc
函数中,并将其传递给
S_Canvas
我可能记得不好,但我认为tkinter不支持直接向回调函数传递参数。作为解决方法,您可以使用lambda函数:

Button_1 = tk.Button(Frame_1,
                     text = u"Draw",
                     width = 20,
                     height=10,
                     bg= "green",
                     command = lambda: DrawFunc(targetCanvas))
但是,如果要重用此命令,必须定义一个不带参数的
draw\u func\u命令
函数:

def draw_func_command():
    global S_Canvas
    DrawFunc(S_Canvas)
但是,您需要将
S_Canvas
声明为全局… 为了避免这种情况,实现UI元素的一般方法是将它们声明为类。不过,我不打算在这里进一步阐述,因为这是一个广泛的话题,有点超出了问题的范围。

要删除第一行,有点棘手。实际上,
Canvas.create\u line
返回一个对象,即绘制的线。要删除它,必须将其存储在变量中,然后对其调用
delete
函数。

代码的问题是函数不在同一个类中,因此变量必须相互传递… 至于擦除画布问题,请在
DrawFunc
函数中添加一个
oldLine
参数,然后在函数体中调用
oldLine.delete()

currentLine = S_Canvas.create_line(50, 250, 250, 70, fill="red")

Button1=按钮(…,command=lambda:DrawFunc(targetCanvas,currentLine))非常感谢!现在程序可以在窗口中绘制第二条线。但是你能告诉我如何删除第一行吗?为了删除第一行,我尝试了一种非常初学者的方法。我在子函数中再次画了相同的线,以覆盖旧的线。我使用了窗口的背景色。但是这条线似乎移到了另一个位置,我现在有三条线。@doglas,不客气:)不过,为了进一步应用和理解,我建议做同样的事情,但要处理对象。提示:您应该只编写一个类,即
Window
。谢谢您的提示。我必须承认,我从来没有想到过在这个任务中使用class方法。事实上,我从来没有试过为tkinter上课。但我会努力的。再次感谢!非常感谢你!现在程序可以在窗口中绘制第二条线。但是你能告诉我如何删除第一行吗?为了删除第一行,我尝试了一种非常初学者的方法。我在子函数中再次画了相同的线,以覆盖旧的线。我使用了窗口的背景色。但是这条线似乎移到了另一个位置,我现在有三条线。@doglas,不客气:)不过,为了进一步应用和理解,我建议做同样的事情,但要处理对象。提示:您应该只编写一个类,即
Window
。谢谢您的提示。我必须承认,我从来没有想到过在这个任务中使用class方法。事实上,我从来没有试过为tkinter上课。但我会努力的。再次感谢!