본문 바로가기
컴퓨터 관련/Linux || Unix

[GTK+] 2. GTK+ 기본 예제

by _BlankSpace 2017. 6. 12.

 0. GTK+ 실행 방법 

GTK+를 입문하면서, 가장 어려웠던 것은 컴파일 방법이었던 것 같습니다. 물론, 터미널에서 소수의 파일을 컴파일 하는 것은 플래그 몇개를 조합하면 쉽게 컴파일할 수 있습니다.


하지만, 규모가 있는 프로그램이라면? 또는, 제대로 된 프로그램을 개발하고자 하여, h, cpp 또는 부모와 자식 클래스로 등등의 디자인을 첨가한 프로그래밍을 한다고 생각하겠습니다.


이럴 때도 일일히 컴파일을 하기위해서 모든 파일명을 적고 계시지는 않을 것입니다. (하신다면 굳이 말리지는 않겠습니다. 본인이 해결 방법을 찾으려고 나설 테니깐 말입니다.)


정답은 여러가지겠지만, 제가 소개하는 방법은 Makefile을 작성하는 것입니다. 하지만, GTK 프로그래밍을 하면서 Makefile 작성이라니.. 충분한 예제도 있지 않습니다. 이러한 분들을 위해서.. GTK 프로그래밍을 위한 Makefile 작성법을 다음 포스팅에 정리해두었습니다. 1. GTK+ 소개 포스팅을 참고하시길 바랍니다.,

  1. GTK+ 창 띄우기

프로그래밍 입문자들이 언어를 처음 공부할 때, 가장 먼저 출력하는 문자열이라면 "Hello World" 일 것입니다. 그렇다면, GUI에서 "Hello World"와 같이 가장 먼저 접하게 되는 것은 무엇일까요.


저의 생각으로는 그래픽 창을 띄우는 것이 가장 먼저 해야할 일이 아닐까 싶습니다. 따라서 가장 먼저, 저는 GTK+를 이용하여 창을 띄우는 예제로 GTK+ 세계로 들어가고자 합니다.


GtkEx1.cpp

1
2
3
4
5
6
7
8
9
10
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
    GtkWidget* window;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_widget_show(window);
    gtk_main ();
    return 0;
}
cs


위의 예제를 컴파일하여, 실행해보시기 바랍니다. 가장 기본적인 GTK+를 이용한 창 띄우기를 보실 수 있으실 것입니다.


아! 컴파일 하는 방법을 모르시겠다구요? 컴파일에 필요한 커맨드는 다음과 같습니다.


gcc GtkEx1.cpp -o base `pkg-config --cflags --libs gtk+-2.0`


그럼 첫 예제를 이용하여, GTK+ 함수들을 설명하겠습니다.


gtk_init (&argc, &argv);

- 디폴트로 비주얼과 칼라맵 등 몇 가지를 세팅한 후, 다음 인자로 넘어갑니다. 이 함수는 사용할 라이브러리를 초기화 하고, 디폴트로 Signal handler를 셋업하며, 명령 행을 통하여 프로그램에 전해진 인자들 중에서 아래의 것들을 찾아서 체크한다고 생각하시면 되겠습니다.


* gtk-module

* g-fatal-warnings

* gtk-debug

* gtk-no-debug

* gdk-debug

* gdk-no-debug

* display

* sync

* name

* class


window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

gtk_widget_show (window);

- 위의 두 줄은 Window를 만들고 보여주는 역할을 합니다.

- GTK_WINDOW_TOPLEVEL이라는 인자는 Window 매니저의 장식과 위치 설정에 따르게 합니다.

- 0x0 크기의 window를 만들지 않고, child가 없는 window는 디폴트 값인 200 x 200 크기로 만들어집니다.

- 순서 없는 목록 gtk_widget_show() 함수는 이 widget의 속성에 대한 세팅이 끝났음을 GTK에 알려줍니다. 이후, 해당 widget은 보여집니다.


 2. 가운데에 GTK+ 창 띄우기 

앞서서, GTK+를 이용하여 창을 띄우는 방법을 소개하였습니다.

그럼 이러한 창을 자신의 마음대로 띄우는 곳을 설정하는 방법도 있지 않을까요? 이번에는 가운데에 창을 띄우는 방법을 소개하고자 합니다.


CenterWindow.c

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <gtk/gtk.h>
int main(int argc, char* argv[])
{
    GtkWidget* window;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Center");
    gtk_window_set_default_size(GTK_WINDOW(window), 230150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    gtk_widget_show(window);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit),
        NULL);
    gtk_main();
    return 0;
}
cs


gtk_window_set_title(GTK_WINDOW(window), "Center");

- gtk_window_set_title()은 window 창 이름을 설정합니다. 설정하지 않는다면, source 파일의 이름으로 대체하게 됩니다.


gtk_window_set_default_size(GTK_WINDOW(window), 230, 150);

- gtk_window_set_default_size()는 230×150에 window 사이즈를 설정합니다.

- window manager에서 제공하는 데코레이션을 제외한 클라이언트 공간을 말합니다.


gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);

- gtk_window_set_position()의 GTK_WIN_POS_CENTER 상수는 프로그램을 스크린의 가운데에 놓겠다는 뜻입니다. 이 방법을 사용하게 된다면 가운데 뿐만 아니라 다양한 곳에 둘 수도 있겠습니다.


 3. Application Icon 출력 

Application Icon을 출력하는 것은 간단하게 말하자면 아이콘을 뜻합니다. 보통 프로그램을 실행하시려고 바탕화면의 아이콘을 더블 클릭합니다. 이렇게 클릭할 때의 그림을 아이콘이라고 하는 데, GTK+도 아이콘을 설정할 수 있습니다.


ApplicationIcon.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <gtk/gtk.h>
GdkPixbuf *create_pixbuf(const gchar* filename)
{
    GdkPixbuf* pixbuf;
    GError* error = NULL;
    pixbuf = gdk_pixbuf_new_from_file(filename, &error);
    if (!pixbuf) {
    fprintf(stderr, "%s\n", error->message);
    g_error_free(error);
    }
    return pixbuf;
}
int main(int argc, char* argv[])
{
    GtkWidget* window;
    GdkPixbuf* icon;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Icon");
    gtk_window_set_default_size(GTK_WINDOW(window), 230150);
    gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    icon = create_pixbuf("/home/bs/Desktop/cryrin.jpg");
    gtk_window_set_icon(GTK_WINDOW(window), icon);
    gtk_widget_show(window);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    g_object_unref(icon);
    gtk_main();
    return 0;
}
cs


대부분의 window manager는 titlebar의 왼쪽 모서리나 taskbar에 아이콘을 출력합니다.


pixbuf = gdk_pixbuf_new_from_file(filename, &error);

- gdk_pixbuf_new_from_file() 함수는 파일에서 이미지를 로딩하여, 새로운 pixbuf를 생성합니다. 이때, 파일 포맷은 자동으로 정해집니다. 만약, NULL이 반환된다면 error가 set됩니다.


if (!pixbuf) {

fprintf(stderr, "%s\n", error->message);

g_error_free(error);

}

- icon이 로드되지 않았다면 error 메시지가 출력됩니다. 예외 처리라고 할 수 있겠습니다.


icon = create_pixbuf("web.png");

gtk_window_set_icon(GTK_WINDOW(window), icon);

- gtk_window_set_icon()은 window에 icon을 출력합니다.

- create_pixbuf()는 PNG file로 GdkPixbuf를 생성합니다.


g_object_unref(icon);

- g_object_unref()은 pixbuf 오브젝트의 reference count를 감소시킨다. reference count가 0으로 떨

어지면 객체가 finalize된다. (메모리가 free된다.)


 4. Tooltip 

Tooltip이라는 단어는 생소하실 겁니다. 이것은 Object에 대해서 간단한 정보를 제공하는 작은 사각형의 window라고 할 수 있습니다. 보통 버튼에 가만히 커서를 두고 있을 때, 작은 말풍선이 하나 뜨는 것을 보신 적이 있으실 겁니다. 그러한 효과를 만들어 내는것이라고 할 수 있습니다.


TooltipEx.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#include <gtk/gtk.h>
int main(int argc, char* argv[]) {
    GtkWidget* window;
    GtkWidget* button;
    GtkWidget* halign;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Tooltip");
    gtk_window_set_default_size(GTK_WINDOW(window), 300200);
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);
    button = gtk_button_new_with_label("Button");
    gtk_widget_set_tooltip_text(button, "Button widget");
    halign = gtk_alignment_new(0000);
    gtk_container_add(GTK_CONTAINER(halign), button);
    gtk_container_add(GTK_CONTAINER(window), halign);
    gtk_widget_show_all(window);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_main();
    return 0;
}
cs


gtk_container_set_border_width(GTK_CONTAINER(window), 15);

- gtk_container_set_border_width()은 window 가장자리의 테투리 사이즈를 설정합니다.


gtk_widget_set_tooltip_text(button, "Button widget");

- gtk_widget_set_tooltip_text()은 주어진 widget에 대한 기본적인 tooltip을 설정합니다.


halign = gtk_alignment_new(0, 0, 0, 0);

gtk_container_add(GTK_CONTAINER(halign), button);

- GtkAlignment는 child를 window의 양쪽에 정렬하는 데 사용합니다. 위와 같은 경우는 버튼이 window의 왼쪽 위 구석에 위치하게 됩니다.

- 1, 2번 파라미터는 xalign과 yalign이다. xalign은 left alignment를 의미하고, yalign은 top alignment를 의미한다.

- 3, 4번 파라미터는 scaling value(widget 크기)이다. 4개의 파라미터는 floating 값으로 0.0 부터 1.0까지가 범위이다.


 5. Mnemonic 

Mnemonic이란 widget을 활성화하는 단축키를 말합니다. 보통 ALT + 설정 키를 누르면 단축키를 활성화하는 효과를 얻을 수 있는 기능이라고 할 수 있습니다.


MnemonicEx.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <gtk/gtk.h>
void print_msg(GtkWidget *widget, gpointer window) {
    g_print("Button clicked\n");
}
int main(int argc, char *argv[]) {
    GtkWidget* window;
    GtkWidget* button;
    GtkWidget* halign;
    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Mnemonic");
    gtk_window_set_default_size(GTK_WINDOW(window), 300200);
    gtk_container_set_border_width(GTK_CONTAINER(window), 15);
    button = gtk_button_new_with_mnemonic("_Button");
    g_signal_connect(button, "clicked", G_CALLBACK(print_msg), NULL);
    halign = gtk_alignment_new(5555);
    gtk_container_add(GTK_CONTAINER(halign), button);
    gtk_container_add(GTK_CONTAINER(window), halign);
    gtk_widget_show_all(window);
    g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
    gtk_main();
    return 0;
}
cs

button = gtk_button_new_with_mnemonic("_Button");

- gtk_button_new_with_mnemonic() 함수는 label을 포함하는 새로운 GtkButton를 생성합니다.

g_signal_connect(button, "clicked", G_CALLBACK(print_msg), NULL);

 - 버튼을 누르면 메시지가 콘솔에 출력됩니다.


위의 설명한 함수들은 앞으로도 자주 사용하게 되는 GTK+의 간단하지만 중요한 함수라고 할 수 있습니다. GTK+프로그래밍을 하고자 하시는 분들이라면 꼭 용도를 이해하셨으면 좋겠습니다.


이상 포스팅을 마치겠습니다. 저의 글을 읽어주셔서 감사합니다. 부족한 내용이 있으시다면 댓글 남겨주시기 바랍니다.


예제는 https://developer.gnome.org/gtkmm-tutorial/stable/index.html.en 를 참고하였습니다.

해당 예제는 다음 사이트를 참고하시기 바랍니다.

https://github.com/blankspace-dev/C-/blob/master/2017/06/12/


제 글이 도움이 되셨거나 공감이 되시는 부분이 있으셨다면, 밑에 있는 공감 버튼 한 번씩 꾸욱 눌러주시면 감사하겠습니다.


공감 버튼은 저에게 큰 도움이 됩니다. 감사합니다.

댓글