2017-10-26 4 views
0

これはおそらく最も簡単な質問です。しかし、私はTkinterを学び始めています。マウスクリックがGUI上で起きたときのイベントをどのように参照するのか分かりません。Tkinterを使ってPython Canvasでペイントイベントを参照する方法はありますか?

キャンバスをクリックするといくつかの点を描きたいと思います。ペイント関数でキャンバス変数を参照することはできません。私は例を試みるたび

コードのこの作品は、SO

にここで問題に基づいており、私は、これは単純なミスである

NameError: name 'canvas' is not defined;

def main(): 
    master = Tk() 
    # Right side of the screen/img holder 
    right_frame = Frame(master, width=500, height=500, cursor="dot") 
    right_frame.pack(side=LEFT) 

    # Retrieve image 
    image = Image.open("./image/demo.JPG") 
    image = image.resize((800, 700), Image.ANTIALIAS) 
    photo = ImageTk.PhotoImage(image) 

    # Create canvas 
    canvas = Canvas(right_frame, width=800, height=700) 
    canvas.create_image(0, 0, image=photo, anchor="nw") 
    canvas.pack() 
    canvas.bind("<B1-Motion>", paint) 
    message = Label(right_frame, text="Press the mouse to draw") 
    message.pack(side=BOTTOM) 


    mainloop() 


def paint(event): 
    python_green = "#476042" 
    x1, y1 = (event.x - 1), (event.y - 1) 
    x2, y2 = (event.x + 1), (event.y + 1) 
    canvas.create_oval(x1, y1, x2, y2, fill=python_green) 


if __name__ == "__main__": 
    main() 
+0

pandasタグの用途がわからないので、より関連性の高いものに置き換えてください。 –

+0

アップしていただきありがとうございます。私は質問を提出したときにそれが選択されたのを見ませんでした。 –

答えて

2

を言うペイント機能でエラーが出ますPythonのスコープ規則を使用しています。関数内で作成する変数は、その関数外では使用できません。

>>> def func(): 
... a = 42 
... 
>>> func() 
>>> a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'a' is not defined 

ペイント機能にキャンバスを渡す必要があります。 bindでこれを行うには、functools.partial関数で行うことができる「クロージャ」を作成する必要があります。

from tkinter import * 
from functools import partial 

def main(): 
    master = Tk() 
    # Right side of the screen/img holder 
    right_frame = Frame(master, width=500, height=500, cursor="dot") 
    right_frame.pack(side=LEFT) 

    # Create canvas 
    canvas = Canvas(right_frame, width=800, height=700) 
    canvas.create_image(0, 0, image=photo, anchor="nw") 
    canvas.pack() 
    canvas.bind("<B1-Motion>", partial(paint, canvas)) 
    message = Label(right_frame, text="Press the mouse to draw") 
    message.pack(side=BOTTOM) 

    mainloop() 

def paint(canvas, event): 
    python_green = "#476042" 
    x1, y1 = (event.x - 1), (event.y - 1) 
    x2, y2 = (event.x + 1), (event.y + 1) 
    canvas.create_oval(x1, y1, x2, y2, fill=python_green) 

if __name__ == "__main__": 
    main() 

これらの種類のプログラムのクラス構造について考える必要があります。そのため、他の方法で変数を使用できるようにする必要があります。

+0

ありがとうございました。私はクラス構造を作成しました。 –

関連する問題