강의노트 이벤트
- 윈도우 프로그램
명령 바인딩
명령 바인딩은 콜백을 위젯의 이벤트(마우스 클릭, 키 누르기)와 연결하는 방법이다.
애플리케이션을 더욱 인터랙티브하게 만들려면 위젯이 마우스 클릭, 키 누르기와 같은 이벤트에 응답해야 한다.
이를 위해서는 특정 이벤트에 콜백 함수를 할당한다. 이벤트가 발생하면 콜백이 자동으로 호출되어 이벤트를 처리한다.
Tkinter의 일부 위젯에서는 명령 바인딩을 사용하여 콜백 함수를 이벤트와 연결할 수 있다.
즉, 위젯의 명령 옵션에 함수 이름을 지정하여 위젯에서 이벤트가 발생하면 해당 함수가 자동으로 호출되도록 할 수 있다.
명령 바인딩을 사용하려면 우선, 함수를 콜백으로 정의한다. 그런 다음 위젯의 명령 옵션에 함수 이름을 지정한다.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
def button_clicked(): #1
print('Button clicked')
button = ttk.Button(root, text='Click Me', command=button_clicked) #2
button.pack()
root.mainloop()
- 함수를 정의한다.
- 함수를 버튼 위젯의 명령 옵션에 연결한다. 명령 옵션 내에 괄호( ) 없이 콜백을 전달해야 한다. 그렇지 않으면 프로그램이 실행되는 즉시 콜백이 호출된다. 인수를 콜백 함수에 전달하려면 람다 표현식을 사용해야 한다. 먼저 인수를 받는 함수를 정의한다. 그런 다음 람다 표현식을 정의하고 버튼 위젯의 명령 인수에 할당한다. 다음은 람다 표현식 내에서 콜백 함수를 호출한다.
ttk.Button(root, text='Button', command=lambda: callback(args))
다음 프로그램은 버튼 명령과 연결된 콜백 함수에 인수를 전달하는 방법이다.
import tkinter as tk
from tkinter import ttk
root = tk.Tk()
def select(option):
print(option)
ttk.Button(root, text='Rock', command=lambda: select('Rock')).pack()
ttk.Button(root, text='Paper',command=lambda: select('Paper')).pack()
ttk.Button(root, text='Scissors', command=lambda: select('Scissors')).pack()
root.mainloop()
버튼을 클릭하면 버튼의 명령과 연결된 람다 표현식이 실행된다. 이 표현식은 문자열 인수를 사용하여 select() 함수를 호출합니다.
명령 바인딩의 제한 사항
첫째, 명령 옵션은 모든 위젯에서 사용할 수 있는 것이 아니다.
둘째, 리턴 키에는 바인딩되지 않는다.
명령 기능의 바인딩을 쉽게 변경할 수 없다. 이러한 한계를 극복하기 위해 Tkinter는 이벤트 바인딩이라는 함수를 이벤트와 연결하는 대체 방법을 제공한다.
이벤트 바인딩
위젯의 이벤트에 함수를 할당하는 것을 이벤트 바인딩이라고 한다. 이벤트가 발생하면 할당된 함수가 자동으로 호출된다.
모든 Tkinter 위젯이 명령 옵션을 지원하지 않는다. Tkinter는 bind() 메서드를 통해 이벤트 바인딩을 위한 대체 방법을 제공한다.
다음은 bind() 메서드의 일반적인 구문이다.
widget.bind(event, 핸들러, add=None)
위젯에서 이벤트가 발생하면 Tkinter는 이벤트 세부 정보가 포함된 핸들러를 자동으로 호출한다.
다음 프로그램은 '저장' 버튼의 Return 키 누름 이벤트에 return_pressed 함수를 바인딩하는 방법을 설명합니다:
import tkinter as tk
from tkinter import ttk
def return_pressed(event):
print('Return key pressed.')
root = tk.Tk()
btn = ttk.Button(root, text='Save')
btn.bind('' , return_pressed) #1
btn.focus()
btn.pack(expand=True)
root.mainloop()
- 버튼 위젯의 bind() 메서드를 호출하여 Return 키 누름 이벤트를 바인딩한다.
핸들러를 추가로 등록하려면 add 인수에 '+'를 전달하면 된다. 이렇게 하면 동일한 이벤트에 여러 개의 이벤트 핸들러를 등록할 수 있다.
다음 예제는 bind() 메서드를 사용하여 동일한 이벤트에 대해 여러 핸들러를 등록하는 방법을 보여준다.
다음은 '저장' 버튼의 Return 키 누름 이벤트에 log() 함수를 바인딩하는 예시입니다
import tkinter as tk
from tkinter import ttk
def return_pressed(event): #1
print('Return key pressed.')
def log(event): #2
print(event)
root = tk.Tk()
btn = ttk.Button(root, text='Save')
btn.bind('' , return_pressed) #3
btn.bind('' , log, add='+') #4
btn.focus() #5
btn.pack(expand=True)
root.mainloop()
- return_pressed함수를 정의한다.
- log함수를 정의한다. 3~4. 포커스를 버튼으로 이동(#5)하고 Return 키를 누르면 Tkinter는 자동으로 return_pressed 및 log 함수를 호출한다. 이 문에서 세 번째 인수 add = '+' 는 로그( ) 함수인 추가 핸들러를 등록한다. add='+' 인수를 지정하지 않으면 bind( )메서드가 기존 핸들러(return_pressed)를 새 핸들러(log)로 대체한다.
이벤트 패턴
Tkinter는 이벤트 패턴을 사용하여 이벤트 이름과 핸들러를 매핑한다. 예를 들어 <리턴>은 Return 키를 누른 것을 나타냅니다.
다음은 이벤트 패턴의 일반적인 구문이다.
<수정자-유형-디테일>
이 구문에서 이벤트는 꺾쇠 괄호(<>)로 둘러싸여 있다. 꺾쇠 괄호 안에는 0개 이상의 수정자, 이벤트 유형 및 이벤트에 대한 상세 정보가 들어간다.
예를 들어 는 키보드의 A 키를 누른 것을 나타내고, 는 Alt + Ctrl + Delete 키를 누른 것을 나타낸다.
다음 섹션에서는 가장 일반적으로 사용되는 이벤트 수정자, 이벤트 유형 및 이벤트 세부 정보를 보여준다.
이벤트 수정자
수정자 | 설명 | 수정자 | 설명 | |
---|---|---|---|---|
Alt | Alt키를 누른 상태 | Control | Ctrl키를 누른 상태 | |
Shift | Shift키를 누른 상태 | Any | 이벤트 유형을 일반화한다. 예를 들어 는 모든 키의 키 누름에 적용된다. |
이벤트 유형
유형 | 이름 | 설명 |
---|---|---|
36 | Activate | 위젯의 상태 옵션이 비활성에서 활성으로 변경됩니다. |
4 | Button | 마우스 버튼 하나를 누릅니다. |
5 | ButtonRelease | 마우스 버튼 하나가 해제됩니다. |
22 | Configure | 위젯의 크기가 변경됩니다. |
37 | Deactivate | 위젯의 상태 옵션이 활성에서 비활성으로 변경됩니다. |
17 | Destroy | 위젯이 파괴됩니다. |
7 | Enter | 마우스 포인터가 위젯의 보이는 부분으로 이동합니다. |
12 | Expose | 다른 창에 가려져 있던 위젯 또는 애플리케이션의 일부가 표시됩니다. |
9 | FocusIn | 입력 포커스가 위젯으로 이동했습니다. |
10 | FocusOut | 입력 포커스가 위젯 밖으로 이동했습니다. |
2 | KeyPress | 키를 누릅니다. |
3 | KeyRelease | 키가 해제되었습니다. |
8 | Leave | 마우스 포인터가 위젯 밖으로 이동했습니다. |
19 | Map | 팩() 또는 그리드() 메서드를 호출하는 등 위젯이 컨테이너에 배치되고 있습니다. |
6 | Motion | 마우스 포인터가 위젯 내에서 완전히 이동했습니다. |
38 | MouseWheel | 사용자가 마우스 휠을 위아래로 움직였습니다. |
18 | Unmap | 위젯의 매핑이 해제되어 더 이상 표시되지 않습니다(예: 위젯에서 grid_remove() 메서드를 호출할 때). |
15 | Visibility | 애플리케이션 창의 일부가 화면에 표시됩니다. |
이벤트 상세
.keysym | .keycode | .keysym_num | Key |
---|---|---|---|
Alt_L | 64 | 65513 | The left-hand alt key |
Alt_R | 113 | 65514 | The right-hand alt key |
BackSpace | 22 | 65288 | backspace |
Cancel | 110 | 65387 | break |
Caps_Lock | 66 | 65549 | CapsLock |
Control_L | 37 | 65507 | The left-hand control key |
Control_R | 109 | 65508 | The right-hand control key |
Delete | 107 | 65535 | Delete |
Down | 104 | 65364 | ↓ |
End | 103 | 65367 | end |
Escape | 9 | 65307 | esc |
Execute | 111 | 65378 | SysReq |
F1 | 67 | 65470 | Function key F1 |
F2 | 68 | 65471 | Function key F2 |
Fi | 66+i | 65469+i | Function key Fi |
F12 | 96 | 65481 | Function key F12 |
Home | 97 | 65360 | home |
Insert | 106 | 65379 | insert |
Left | 100 | 65361 | ← |
Linefeed | 54 | 106 | Linefeed (control-J) |
KP_0 | 90 | 65438 | 0 on the keypad |
KP_1 | 87 | 65436 | 1 on the keypad |
KP_2 | 88 | 65433 | 2 on the keypad |
KP_3 | 89 | 65435 | 3 on the keypad |
KP_4 | 83 | 65430 | 4 on the keypad |
KP_5 | 84 | 65437 | 5 on the keypad |
KP_6 | 85 | 65432 | 6 on the keypad |
KP_7 | 79 | 65429 | 7 on the keypad |
KP_8 | 80 | 65431 | 8 on the keypad |
KP_9 | 81 | 65434 | 9 on the keypad |
KP_Add | 86 | 65451 | + on the keypad |
KP_Begin | 84 | 65437 | The center key (same key as 5) on the keypad |
KP_Decimal | 91 | 65439 | Decimal (.) on the keypad |
KP_Delete | 91 | 65439 | delete on the keypad |
KP_Divide | 112 | 65455 | / on the keypad |
KP_Down | 88 | 65433 | ↓ on the keypad |
KP_End | 87 | 65436 | end on the keypad |
KP_Enter | 108 | 65421 | enter on the keypad |
KP_Home | 79 | 65429 | home on the keypad |
KP_Insert | 90 | 65438 | insert on the keypad |
KP_Left | 83 | 65430 | ← on the keypad |
KP_Multiply | 63 | 65450 | × on the keypad |
KP_Next | 89 | 65435 | PageDown on the keypad |
KP_Prior | 81 | 65434 | PageUp on the keypad |
KP_Right | 85 | 65432 | → on the keypad |
KP_Subtract | 82 | 65453 | - on the keypad |
KP_Up | 80 | 65431 | ↑ on the keypad |
Next | 105 | 65366 | PageDown |
Num_Lock | 77 | 65407 | NumLock |
Pause | 110 | 65299 | pause |
111 | 65377 | PrintScrn | |
Prior | 99 | 65365 | PageUp |
Return | 36 | 65293 | Enter key |
Right | 102 | 65363 | → |
Scroll_Lock | 78 | 65300 | ScrollLock |
Shift_L | 50 | 65505 | The left-hand shift key |
Shift_R | 62 | 65506 | The right-hand shift key |
Tab | 23 | 65289 | The tab key |
루트 창에 이벤트 바인딩하기
Tkinter를 사용하면 최상위 창에 이벤트를 바인딩할 수도 있다. 다음 예제는 bind()의 구문은 루트 창에서 호출할 수 있다는 점을 제외하면 동일하다.
root.bind('<리턴>', 핸들러)
바인딩 수준
이전 예제에서는 이벤트를 위젯의 특정 인스턴스에 바인딩하는 방법을 배웠다. 이를 인스턴스 수준 바인딩이라고 한다.
Tkinter를 사용하면 위젯의 모든 인스턴스에 이벤트를 바인딩할 수도 있다. 예를 들어 프로그램의 모든 텍스트 상자에 이벤트를 바인딩할 수 있다:
root.bind_class('Entry', '', 붙여넣기)
참고로 Tkinter에서는 엔트리 위젯을 사용하여 텍스트 상자를 만든다.
이벤트를 인스턴스 대신 클래스에 바인딩하기 때문에 이를 클래스 수준 바인딩이라고 한다.
이벤트 바인딩 해제하기
때로는 이전 바인딩의 효과를 취소하고 싶을 때가 있다. 이를 위해 unbind() 메서드를 사용할 수 있다:
widget.unbind(event)
다음 예제는 btn 버튼에서 이벤트의 바인딩을 해제한다 :
btn.unbind('<리턴>')
마우스 이벤트
마우스 이벤트는 클릭할때, 클릭했다 떼었을때, 더블클릭할때, 드래그할때, 마우스가 위젯에 들어왔을때, 마우스가 위젯을 떠났을때 발생한다.
입력이 있을때 발생하는 함수
마우스 이벤트가 발생할때의 이벤트 코드는
클릭할때
버튼 | 클릭할때 | 클릭했다 떼었을때 | 더블 클릭 | 드래그할때 | 위젯에 들어왔을때 | 위젯을 떠났을때 |
---|---|---|---|---|---|---|
모든버튼 | < Button > | < ButtonRelease > | < Double-Button > | < Enter > | < Leave > | |
왼쪽버튼 | < Button-1 > | < ButtonRelease-1 > | < Double-Button-1 > | < B1-Motion > | ||
가운데 버튼 | < Button-2 > | < ButtonRelease-2 > | < Double-Button-2 > | < B2-Motion > | ||
오른쪽버튼 | < Button-3 > | < ButtonRelease-3 > | < Double-Button-3 > | < B3-Motion > |
def 이벤트처리함수(event):
# 처리 내용
위젯.bind("이벤트 작동", 처리함수)
키보드 이벤트
키보드 작동 | 이벤트 코드 |
---|---|
모든 키 | < Key > |
특수 키 | < Return >, < BackSpace >, < Tab >, < Shift_L >, < Control_L >, < Alt_L >, < Pause >, < Caps_Lock >, < Escape >,< End >,< Home >,< Left > |
특수 키 | < Right >,< Up >,< Down >,< Num_Lock >,< Delete >,< F1 > ~ < F12> |
일반 키 | a ~ z, A ~ Z, 0 ~ 9, < space >,< less > |
화살표 키와 조합 | < Shift-Up >,< Shift-Down >,< Shift-Left >,< Shift-Right > |
canvas의 공을 만들고 움직인다.
import tkinter as tk
import time
def moveleft(event):
global aliens
for alien in aliens:
Cvs.move(alien,-10,0)
def moveright(event):
global aliens
for alien in aliens:
Cvs.move(alien,10,0)
def f_quit():
root.destroy()
def f_create():
global aliens
aliens.append(Cvs.create_oval(20, 260, 120, 360, outline='white', fill='blue'))
aliens = []
root = tk.Tk()
Cvs = tk.Canvas(root, width=400, height=400)
Cvs.pack()
Btn1 = tk.Button(root,text='Create',command=f_create)
Btn2 = tk.Button(root,text='Stop',command=f_quit)
Btn1.pack(side='left')
Btn2.pack(side='left')
root.bind("" ,moveleft)
root.bind("" ,moveright)
root.mainloop()
로그인 하면 댓글을 쓸 수 있습니다.