파이썬으로 GUI 프로그래밍을 시작하기 위한 가장 빠른 방법은 Tkinter 모듈을 사용하는 것이다. Tkinter는 쉽게말해 파이썬으로 GUI 윈도우 창을 만들 수 있게 해주는 프레임웤(윈도우 만들기 도구)이라 볼 수 있다.
예를 들어 이 세줄의 코드로 윈도우창을 만들 수 있다.
import tkinter as tk
window = tk.Tk()
window.mainloop()
Tkinter는 파이썬을 위한 Tk GUI toolkit 이다. 리눅스,윈도우,맥OS에 파이썬을 설치할 때 기본으로 포함된다. OS에 상관없이 GUI를 사용할 수 있는 크로스 플랫폼이다. Tk는 툴킷(도구함)을 의미하고 inter는 interface의 의미이다. 즉 TCL/Tk의 파이썬을 위한 인터페이스이다.
Tkinter의 바탕인 Tk 의 개념 설명에 대한 자료가 별로 눈에 띄지 않아서 나름의 방식으로 정리해본다.
우선 Tk는 Toolkit 의 줄임말이다. Tool 은 도구라는 말이고 Toolkit은 도구가 하나가 아니라 여러개를 특정한 목적에 따라 모아놓은 것이다. 구급키트 (first-aid kit) 같은 단어가 이런 경우다. 응급처치에 필요한 도구를 모아놓은 것.
그래서 무엇을 의한 도구냐? GUI 프로그램에 들어가는 기본 요소들의 라이브러리를 모아 둔 것이다. Tk 는 스탠포드 공대 교수 존 오스터 하우트가 30년전에 개발한 크로스 플랫폼, 오픈소스 프로젝트이다. GUI 프로그램에 들어가는 요소들은 거의 표준화가 되어있다. 레이블, 버튼, 입력창, 메세지, 캔버스, 폰트 등 다른 GUI에서도 흔히 사용되는 것들이다. 이것들을 widget 이라 하는데 윈도우 GUI의 component (컴포넌트)라고도 부른다. 다 비슷한 말이다. 요소,컴포넌트,위젯.
https://en.wikipedia.org/wiki/John_Ousterhout오스터 하우트 TK의 창시자
역사가 오래되었음에도 대중에게 이름이 별로 알려지지 않은 것은 아마 MS가 윈도우로 GUI시장을 오랜기간 독점했기 때문일 것이다. 오픈소스 진영 사람들이 GUI 개발에 참여할 때 돈보다는 자신과 동료들에게 필요한 것들을 만들기 시작했던 부분도 있다. 일하다 보니 동료들이 간단한 GUI 기능 하나에도 한참 시간을 보내고 있었던 것이다. 그래서 매우 심플하고 강력한 toolkit 을 개발하기 시작했다.
크로스 플랫폼이 가능해서 여러 OS에서 실행되야 했고, 빠르게 프로토타입을 제작할 수 있게 해주며 용량도 많지 않아서 C 앱으로 임베디드되기 쉬워야 했다. 30년 전의 컴퓨터 성능을 생각하면 지금 시대보다 매우 슬림해야 한다.
이런 개념에서 출발한 것이 TCL이다(TK의 확장판, Tcl/Tk 라고도 부른다.) TCL은 Tool Command Language이다. 도구를 커맨드로 사용하는 스크립팅 언어다. 프로토타입을 빨리 만들거나, 데이타베이스를 테스트하는 등의 목적으로 사용했다.
지금에 와서야 MS도 오픈소스 방침으로 상당히 변하고 있지만 MS의 윈도우 시대에 가리워졌던 사람들의 업적이다. 스마트폰이 나온 지금이야 뭐 윈도우보다 오픈소스를 기반으로한 구글과 애플의 시대지만 그 때는 그랬다.
파이썬이 추구하는 것과도 비슷하다. 코드 세줄로 윈도우창을 띄운다. C의 Window API에 비하면 클릭하는 것과 비슷할 정도다. 다음은 비주얼 스튜디오 C++에서 헬로우 월드창을 만들 때 사용되는 코드이다. 물론 C++ 의 강력함과 파이썬을 비교할 수는 없다. 두 언어간의 차이가 크다는 것이다.
// HelloWindowsDesktop.cpp
// compile with: /D_UNICODE /DUNICODE /DWIN32 /D_WINDOWS /c
#include <windows.h>
#include <stdlib.h>
#include <string.h>
#include <tchar.h>
// Global variables
// The main window class name.
static TCHAR szWindowClass[] = _T("DesktopApp");
// The string that appears in the application's title bar.
static TCHAR szTitle[] = _T("Windows Desktop Guided Tour Application");
HINSTANCE hInst;
// Forward declarations of functions included in this code module:
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int CALLBACK WinMain(
_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPSTR lpCmdLine,
_In_ int nCmdShow
)
{
WNDCLASSEX wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, IDI_APPLICATION);
wcex.hCursor = LoadCursor(NULL, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = NULL;
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, IDI_APPLICATION);
if (!RegisterClassEx(&wcex))
{
MessageBox(NULL,
_T("Call to RegisterClassEx failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
// Store instance handle in our global variable
hInst = hInstance;
// The parameters to CreateWindow explained:
// szWindowClass: the name of the application
// szTitle: the text that appears in the title bar
// WS_OVERLAPPEDWINDOW: the type of window to create
// CW_USEDEFAULT, CW_USEDEFAULT: initial position (x, y)
// 500, 100: initial size (width, length)
// NULL: the parent of this window
// NULL: this application does not have a menu bar
// hInstance: the first parameter from WinMain
// NULL: not used in this application
HWND hWnd = CreateWindow(
szWindowClass,
szTitle,
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, CW_USEDEFAULT,
500, 100,
NULL,
NULL,
hInstance,
NULL
);
if (!hWnd)
{
MessageBox(NULL,
_T("Call to CreateWindow failed!"),
_T("Windows Desktop Guided Tour"),
NULL);
return 1;
}
// The parameters to ShowWindow explained:
// hWnd: the value returned from CreateWindow
// nCmdShow: the fourth parameter from WinMain
ShowWindow(hWnd,
nCmdShow);
UpdateWindow(hWnd);
// Main message loop:
MSG msg;
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return (int) msg.wParam;
}
// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)
//
// PURPOSE: Processes messages for the main window.
//
// WM_PAINT - Paint the main window
// WM_DESTROY - post a quit message and return
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
TCHAR greeting[] = _T("Hello, Windows desktop!");
switch (message)
{
case WM_PAINT:
hdc = BeginPaint(hWnd, &ps);
// Here your application is laid out.
// For this introduction, we just print out "Hello, Windows desktop!"
// in the top left corner.
TextOut(hdc,
5, 5,
greeting, _tcslen(greeting));
// End application-specific layout section.
EndPaint(hWnd, &ps);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
break;
}
return 0;
}
TK는 이렇게 사용한다
스크립팅 언어로 한줄씩 코드를 작성하면 바로 결과를 반영하여 보여준다. ActiveTcl 8.6 버전을 설치하면 Tk 도 같이 설치된다.
참고로 파이썬에서 사용가능한 GUI 프레임웤의 리스트는 아래와 같다. Tk 를 계승하는 프레임웤도 꽤 있다.
https://wiki.python.org/moin/GuiProgramming
* Tkinter 에 관련한 참고 사이트이다
https://realpython.com/python-gui-tkinter/
https://likegeeks.com/python-gui-examples-tkinter-tutorial/
https://www.tutorialspoint.com/python/python_gui_programming.htm
https://docs.python.org/ko/3/library/tkinter.html
https://www.tutorialspoint.com/tcl-tk/index.htm
https://www.guru99.com/tcl-tutorial.html
https://www.tutorialspoint.com/execute_tcl_online.php
https://wiki.python.org/moin/GuiProgramming