python + tkinter:如何使用Canvas作为主函数和子函数?

时间:2016-11-11 08:28:48

标签: python tkinter tkinter-canvas

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

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

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

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

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()

1 个答案:

答案 0 :(得分:2)

要绘制相同的canvas,您的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_func_command函数:

def draw_func_command():
    global S_Canvas
    DrawFunc(S_Canvas)

但是,你需要将S_Canvas声明为全局......

为避免这种情况,实现UI元素的一般方法是将它们声明为类。我不会在这里开发这个,因为这是一个广泛的主题,而且有点超出了这个问题。

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

您的代码的问题是该函数不在同一个类中,因此必须相互传递变量...

至于擦除画布问题,请在oldLine函数中添加DrawFunc参数,然后在其正文中调用oldLine.delete()

currentLine = S_Canvas.create_line(50, 250, 250, 70, fill="red")
Button1 = Button(..., command = lambda: DrawFunc(targetCanvas, currentLine))