프날 오토핫키 강좌  v2

⚠ 이 강좌는 오토핫키 v2를 다룹니다

지금 보시는 강좌는 과거 오랜 시간동안 알려진 오토핫키(v1.1)의 차세대 버전인 오토핫키 v2를 다루고 있습니다.
만약 구버전인 '오토핫키 v1.1'의 강좌를 찾으신다면 프날 오토핫키 강좌(https://pnal.kr)를 봐주시면 되지만, 새로 오토핫키를 배우신다면 v2 버전을 배우시는 것을 강력히 추천드립니다.

73. 이벤트와 콜백 함수


이제 우리가 만든 컨트롤에 생명을 불어넣어 보겠습니다. 아무 역할도 하지 않고 껍데기만 있던 컨트롤에 제 기능을 부여해 보겠습니다.

이벤트

컨트롤과의 상호작용으로 어떤 동작을 하게 하려면 우선 선행되는 조건이 있어야 합니다. 예를 들어서 "버튼을 누를 때 알림 상자를 출력한다" 라는 아주 간단한 GUI 프로그램을 만들기 위해서 아래와 같이 분석해볼 수 있을 것입니다.

조건: 버튼을 누를 때
동작: 알림 상자를 출력

여기서 어떤 동작을 촉발시키기 위해 선행되어야 하는 조건을 이벤트(Event;사건)라고 부릅니다. 따라서 위 예시는 "버튼 클릭 이벤트에 의해 알림 상자를 출력하는 프로그램"이라고 말할 수 있습니다.

콜백

콜백(Callback)은 콜백 함수(Callback function)라고도 하는데, '다른 함수에 인수로 쓰여 촉발되는 함수'를 의미합니다.

1B()
2{
3    MsgBox("안녕 나는 콜백 함수야")
4}
5
6A(B)
A의 인수로 함수 B 그 자체가 전달된 모습을 보세요.

A의 구현은 중요하지 않습니다. 우리가 콜백 함수를 등록하기 위한 함수 A를 직접 구현하진 않을 것입니다. 눈여겨 볼 점은 함수의 인수로 함수가 들어갔다는 사실입니다.

6번 줄에서 함수 A는 함수 B 그 자체를 인수로 하여 호출되었습니다. 이렇게 인수로 들어가서 수행되는 함수를 콜백이라고 부른다고만 알면 되겠습니다.

GuiControl 객체

이전 강에서 Gui.Add() 메서드를 배웠습니다. 그리고 간단히 언급만 했는데, 이 메서드의 반환값이 GuiControl 객체라고 했습니다.

...MyButton := MainGui.Add("Button", "x20 y20 w70", "클릭")
버튼 객체를 MyButton 변수에 담는 모습

위와 같이 Gui.Add() 메서드의 반환값을 변수에 담을 수 있습니다. 이제 저 변수엔 GuiControl 객체가 담겨있는 셈입니다. (쉽게 이해하기 위해, 변수에 만들어진 컨트롤이 담겨있다고 보시면 됩니다.)

GuiControl.OnEvent()

컨트롤에 이벤트가 발생할 때 호출할 함수를 등록하기 위해선 GuiControl.OnEvent() 메서드를 이용합니다. 메서드의 원형을 보겠습니다.

GuiControl.OnEvent(EventName, Callback [, AddRemove])

하나씩 살펴보면 어렵지 않습니다.

  • EventName: 어떤 이벤트에 의해 함수를 실행시킬지? 문자열로 지정해주는 옵션입니다.
  • Callback: 위의 이벤트가 촉발됐을 때 어떤 함수를 실행시킬지? 콜백 함수를 넣어줍니다.
  • AddRemove: 중요하지 않고 초급 수준에서 설명하기 곤란하므로 설명을 생략합니다.

먼저 EventName 매개변수엔 아래와 이벤트 목록 중 하나를 문자열로 넣어줍니다.

이벤트역할
Change컨트롤의 값이 바뀌었을 때
Click컨트롤을 클릭했을 때
DoubleClick컨트롤을 더블 클릭했을 때

더욱 많은 컨트롤 이벤트가 있지만 가장 많이 쓰이는 세 가지만 준비했습니다. 다른 이벤트는 이벤트 목록 문서를 참고해주세요.

Callback 매개변수로는 이벤트가 발생할 때 호출할 콜백 함수를 전달해줍니다. 즉 "버튼을 클릭했을 때 MyFunc() 함수를 수행"과 같은 동작은 아래와 같이 적을 수 있습니다.

...MyButton.OnEvent("Click", MyFunc)

콜백 함수 디자인

GuiControl.OnEvent() 함수로 이벤트에 콜백 함수를 등록해주면, 해당 이벤트가 유발됐을 때 콜백 함수를 수행한다고 했습니다.

저 콜백 함수의 본문은 자유롭게 짜시면 되고, 매개변수는 정해져 있습니다. 문제는 이 매개변수가 이벤트에 따라 각각 다르게 정해져 있다는 것입니다. 일단 위에서 설명한 세 개의 이벤트는 각각 동일한 콜백 함수 양식을 갖고 있습니다.

이벤트콜백 함수의 매개변수 양식
ChangeCallbackFunc(GuiCtrlObj, Info)
ClickCallbackFunc(GuiCtrlObj, Info)
DoubleClickCallbackFunc(GuiCtrlObj, Info)

매개변수의 이름은 자유이나, 각 매개변수에 무엇이 전달되는지 알아보기 쉽게 위와 같이 적는 것입니다. 꼭 매개변수의 이름이 GuiCtrlObj와 Info일 이유는 없습니다.

일단 모든 콜백 함수의 첫 매개변수 GuiCtrlObj엔 이벤트가 유발된 컨트롤 객체가 담깁니다. 버튼을 클릭해서 Click 이벤트에 의해 콜백 함수가 호출되었다면 그 콜백 함수의 첫번째 매개변수는 해당 버튼 객체가 담겨있을 것입니다.

두 번째 매개변수 Info엔 이벤트 정보가 담기는데, 예를 들어서 Slider 컨트롤에 Change 이벤트를 등록했을 경우엔 해당 매개변수로 "슬라이더가 어느 방향으로 움직였는지"에 관한 정보가 전달됩니다. 다만 대부분의 상황에서 Info 매개변수로 들어오는 정보는 쓸모가 없습니다. Click이나 DoubleClick 이벤트의 경우도 마찬가지로 별 의미는 없고, 일부 컨트롤에서만 이벤트 정보가 담깁니다.

그러나 반드시 정해진 개수대로의 매개변수를 가진 콜백 함수를 만들어야 합니다. 그것만 지켜주시면 콜백 함수 촉발시에 각 매개변수로 적당한 값이 들어갑니다. 그 값으로 첫 번째 매개변수에는 'GuiControl 객체', 두 번째 매개변수엔 '이벤트 정보'가 들어간다는 것이지요.

즉, 최종적으로 여러분이 구성해야할 코드 조각은 아래와 같습니다.

~창 및 컨트롤 생성 구문 생략
1MyControl.OnEvent("Click", MyButton_OnClick) ;컨트롤 이벤트 등록
2return
3
4MyButton_OnClick(obj, info)
5{
6    ... ;이벤트 발생 시 할 일
7}

번외: 창 이벤트

GuiControl 객체가 아닌, Gui 객체에도 OnEvent() 메서드가 있습니다. 사실 71강 표에 "창 이벤트를 감지하도록 설정합니다"라는 기능으로 짧게 적고 넘어간 부분인데, 이젠 사용할 수 있겠네요.

Gui.OnEvent()의 사용법은 GuiControl.OnEvent()의 사용법과 같습니다. 이벤트 목록에서 창 이벤트 또한 확인할 수 있습니다. 제공해드린 문서에서 각 이벤트 이름을 누르면 콜백 함수의 양식 또한 알 수 있습니다. Close 이벤트의 콜백 함수 매개변수는 단 한 개라는 것을 알 수 있습니다. 강좌에서 중요한 내용은 아니므로 문서로 대체하겠습니다.

가장 중요한 Close 이벤트의 용례 하나만 말씀드리겠습니다. '핫키가 있어서 자동으로 종료되지 않는 GUI 프로그램'의 경우, GUI의 창이 닫히면 Close 이벤트를 통해 ExitApp 함수를 호출하도록 하는 식으로 구현하는 경우가 많습니다. 71강의 실습 예제가 이와 같은 경우입니다.

실습

분량이 좀 많았네요 수고 많으셨습니다. 실습을 통해 오늘 배운 내용을 이용해 보겠습니다.

1. 버튼을 클릭하면 알림 상자 띄우기

1Main := Gui(, "73강 연습")
2PopButton := Main.Add("Button", "x30 y30 w200 h50", "클릭")
3Main.Show("w260 h110")
4PopButton.OnEvent("Click", PopButton_OnClick)
5return
6
7PopButton_OnClick(obj, info)
8{
9    MsgBox("버튼이 클릭되었습니다.")
10}
예제 1. 클릭하면 알림 상자가 나타나는 버튼이 있는 창 만들기

위 예제는 아래 이미지와 같은 창을 생성합니다.

클릭이라고 적힌 버튼이 있는 프로그램 창의 모습 사진 1. 생성된 창의 모습

버튼을 누르면 PopButton_OnClick 이라는 콜백 함수가 촉발되어 알림 상자가 출력될 것입니다.

다시 한번 말씀드리지만 obj, info 매개변수는 단지 임의로 정해준 이름이며, 첫번째 매개변수론 컨트롤 객체가, 두 번째 매개변수론 이벤트 정보가 전달되기에 이와 같은 이름을 사용한 것입니다. 위 예제처럼 이 매개변수를 사용하지 않더라도 콜백 함수는 정해진 매개변수 개수대로 작성해주어야 합니다.

더욱 복잡한 예제는 향후 진행될 내용과 경험을 통해 다뤄보도록 하고요, 일단 기본 개념만 알고 다음 강으로 넘어갑시다.

질문하러 가기