Lecture 이벤트

Lecture • Views 28 • Comments 0 • Last Updated at 4 weeks ago  
  • 윈도우 프로그램
  • 윈도우 프로그램

명령 바인딩

명령 바인딩은 콜백을 위젯의 이벤트(마우스 클릭, 키 누르기)와 연결하는 방법이다.

애플리케이션을 더욱 인터랙티브하게 만들려면 위젯이 마우스 클릭, 키 누르기와 같은 이벤트에 응답해야 한다.

이를 위해서는 특정 이벤트에 콜백 함수를 할당한다. 이벤트가 발생하면 콜백이 자동으로 호출되어 이벤트를 처리한다.

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()
  1. 함수를 정의한다.
  2. 함수를 버튼 위젯의 명령 옵션에 연결한다. 명령 옵션 내에 괄호( ) 없이 콜백을 전달해야 한다. 그렇지 않으면 프로그램이 실행되는 즉시 콜백이 호출된다. 인수를 콜백 함수에 전달하려면 람다 표현식을 사용해야 한다. 먼저 인수를 받는 함수를 정의한다. 그런 다음 람다 표현식을 정의하고 버튼 위젯의 명령 인수에 할당한다. 다음은 람다 표현식 내에서 콜백 함수를 호출한다.
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()
  1. 버튼 위젯의 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()
  1. return_pressed함수를 정의한다.
  2. 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
Print 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()
previous article
next article
Comments
Feel free to ask a question, answer or comment, etc.