0. 들어가기 전.. |
이번에 다룰 부분은 GTK+ 프로그래밍을 할 때, Layout을 관리하기 위한 함수들을 정리하려고 합니다.
이 부분은 자바의 swing과 같은 GUI를 프로그래밍할 때, 꼭 필요한 부분이라고 할 수 있습니다.
GTK+ 도 역시, GUI 프로그래밍이므로, layout을 관리하기 위한 여러 가지의 함수들이 있습니다.
지금부터 그러한 함수들을 소개하도록 하겠습니다.
1. GtkFixed |
먼저, GtkFixed 함수는 고정된 위치와 사이즈로 child widget을 위치시키는 기능을 합니다. 1
다시 말하자면, 이 기능은 프로그램을 개발하는 사람 마음대로 widget의 위치를 정할 수 있다는 뜻입니다.
예제를 통해 설명을 이어가겠습니다.
GtkFixedEx.c
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 30 31 | #include <gtk/gtk.h> int main(int argc, char* argv[]) { GtkWidget* window; GtkWidget* fixed; GtkWidget* btn1; GtkWidget* btn2; GtkWidget* btn3; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GtkFixed"); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); fixed = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), fixed); btn1 = gtk_button_new_with_label("Button"); gtk_fixed_put(GTK_FIXED(fixed), btn1, 150, 50); gtk_widget_set_size_request(btn1, 80, 30); btn2 = gtk_button_new_with_label("Button"); gtk_fixed_put(GTK_FIXED(fixed), btn2, 15, 15); gtk_widget_set_size_request(btn2, 80, 30); btn3 = gtk_button_new_with_label("Button"); gtk_fixed_put(GTK_FIXED(fixed), btn3, 100, 100); gtk_widget_set_size_request(btn3, 80, 30); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; } | cs |
위와 같이 fixed 방법으로 레이아웃을 설정하면 application의 window가 resize해도 버튼의 자리나 크기는 변하지 않습니다. 즉, 해당 widget은 고정된다고 생각하면 될 것입니다.
fixed = gtk_fixed_new();
- get_fixed_new() 함수는 GtkFixed 컨테이너에 생성한다.
gtk_fixed_put(GTK_FIXED(fixed), btn1, 150, 50);
- 첫 번째 버튼은 150, 50 위치에 고정된다.
gtk_widget_set_size_request(btn1, 80, 30);
- 첫 번째 버튼의 크기를 재조정한다.
2. GtkAlignment |
GtkAlignment는 widget의 정렬을 제어하는 기능입니다. 또한, scailing도 관리할 수 있습니다.
GtkAlignment.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #include <gtk/gtk.h> int main(int argc, char* argv[]) { GtkWidget* window; GtkWidget* align; GtkWidget* lbl; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GtkAlignment"); gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_container_set_border_width(GTK_CONTAINER(window), 5); align = gtk_alignment_new(0, 1, 0, 0); lbl = gtk_label_new("bottom-left"); gtk_container_add(GTK_CONTAINER(align), lbl); gtk_container_add(GTK_CONTAINER(window), align); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; } | cs |
예제를 실행해보시면, bottom-left라는 레이블이 정렬된 것을 보실 수 있습니다. 이러한 효과를 얻고자 할 때, 사용하는 함수입니다.
align = gtk_alignment_new(1, 1, 1, 1);
- gtk_alignment_new()는 GtkAlignment 컨테이너를 생성합니다.
- 파라미터는 0부터 1까지의 값으로 설정할 수 있습니다.
- 첫 번째 인자 : horizontal alignment 0 < a < 1
- 두 번째 인자 : vertical alignment 0 < a < 1
- 세 번째 인자 : horizontal scale, 수평으로 사용되지 않은 공간을 채웁니다,
- 네 번째 인자 : vertical scale, 수직으로 사용되지 않은 공간을 채웁니다.
lbl = gtk_label_new("bottom-left");
- gtk_label_new() 함수는 label widget을 생성합니다.
* gtk_container_add(GTK_CONTAINER(align), lbl);
- GtkAlignment 컨테이너에 label을 더합니다.
* gtk_container_add(GTK_CONTAINER(window), align);
- window에 alignment 컨테이너를 위치시킵니다.
3. GtkVBox, GtkHBox |
이 기능은 레이아웃 중에서, 가장 많이 쓰는 레이아웃 방법이라고 생각합니다. 저 역시도, 이 방법을 자주 사용하여 프로그램을 구현했던 기억이 남습니다.
- GtkVBox는 수평 박스 컨테이너입니다. 하나의 칼럼에 chile widget을 놓습니다.
- GtkHBox는 수직 박스 컨테이너입니다. 하나의 열에 chile widget을 놓습니다.
GtkVBoxEx.c
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 30 31 32 | #include <gtk/gtk.h> int main(int argc, char* argv[]) { GtkWidget* window; GtkWidget* vbox; GtkWidget* settings; GtkWidget* accounts; GtkWidget* loans; GtkWidget* cash; GtkWidget* debts; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 230, 250); gtk_window_set_title(GTK_WINDOW(window), "GtkVBox"); gtk_container_set_border_width(GTK_CONTAINER(window), 5); vbox = gtk_vbox_new(TRUE, 1); gtk_container_add(GTK_CONTAINER(window), vbox); settings = gtk_button_new_with_label("Settings"); accounts = gtk_button_new_with_label("Accounts"); loans = gtk_button_new_with_label("Loans"); cash = gtk_button_new_with_label("Cash"); debts = gtk_button_new_with_label("Debts"); gtk_box_pack_start(GTK_BOX(vbox), settings, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), accounts, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), loans, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), cash, TRUE, TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), debts, TRUE, TRUE, 0); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show_all(window); gtk_main(); return 0; } | cs |
위의 예제를 실행해보셨나요? 그럼 흔하게 볼 수 있는 버튼 위젯들이 가지런히 놓여있는 것을 보실 수 있습니다.
이 예제는 vbox를 이용하였으므로, 위젯들이 하나의 칼럼에 가지런히 놓이면서, 밑으로 나열되는 것을 볼 수 있습니다.
그렇다면, hbox를 이용한다면 어떨까요? 당연히, 하나의 열에 자식 위젯들이 놓이겠습니다. 이 예제는 vbox 대신에 hbox를 사용하면 되는 것이므로 궁금하신 분들은 직접 해보시기 바랍니다.
vbox = gtk_vbox_new(TRUE, 1);
- gtk_vbox_new() 함수는 GtkVBox 컨테이너를 생성합니다.
- 첫 번째 인자는 homogeneous 인자로 TRUE로 설정하면, 모든 버튼은 같은 사이즈로 설정됩니다.
- 두 번째 인자는 spacing. 여백의 크기라고 생각하면 되겠습니다.
gtk_box_pack_start(GTK_BOX(vbox), settings, TRUE, TRUE, 0);
- 첫 번째 인자 : box container
- 두 번째 인자 : child widget
- 세 번째 인자 : expand
- 네 번째 인자 : fill
- 다섯 번째 인자 : padding
- expand가 FALSE이면 fill 인자는 효과가 없습니다. 만약 homogeneous가 TRUE이면 expand는 효과가 없습니다. 이 부분은 직접 테스트하면서 하시는 것이 가장 효과적으로 학습하시는 데 도움이 되실 것입니다.
4. GtkTable |
GtkTable은 이름에서 알 수 있는 것처럼 테이블 형태로 열과 행을 배치할 수 있는 함수입니다.
GtkTableEx.c
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 30 31 32 33 34 35 | #include <gtk/gtk.h> int main(int argc, char *argv[]) { int i; int j; int pos = 0; GtkWidget *window; GtkWidget *table; GtkWidget *button; gchar *values[20] = { "7", "8", "9", "/", "~", "4", "5", "6", "*", "!", "1", "2", "3", "-", "@", "0", ".", "=", "+", "#" }; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 200, 200); gtk_window_set_title(GTK_WINDOW(window), "GtkTable"); gtk_container_set_border_width(GTK_CONTAINER(window), 5); table = gtk_table_new(4, 5, TRUE); gtk_table_set_row_spacings(GTK_TABLE(table), 1); gtk_table_set_col_spacings(GTK_TABLE(table), 1); for (i = 0; i < 4; i++) { for (j = 0; j < 5; j++) { button = gtk_button_new_with_label(values[pos]); gtk_table_attach_defaults(GTK_TABLE(table), button, j, j+1, i, i+1); pos++; } } gtk_container_add(GTK_CONTAINER(window), table); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; } | cs |
예제를 실행하시면, 아주 간단한 계산기 형태로 widget들이 배치된 것을 확인할 수 있습니다. 이처럼 테이블 형태로 위젯들을 배치하고자 할 때, 이 함수를 사용하시면 되겠습니다.
table = gtk_table_new(4, 5, TRUE);
- GtkTable widget을 4열 5행으로 만듭니다.
- 세 번째 파라미터가 TRUE이면 모든 테이블의 셀은 가장 큰 widget에 포함하는 셀의 사이즈에 맞추어집니다.
gtk_table_set_row_spacings(GTK_TABLE(table), 2);
gtk_table_set_col_spacings(GTK_TABLE(table), 2);
- 테이블의 열과 행 공간을 설정합니다.
gtk_table_attach_defaults(GTK_TABLE(table), button, j, j+1, i, i+1 );
- 동일한 padding과 expansion 옵션으로 table 컨테이너에 child를 더합니다.
5. 추가적으로 도움이 되는 함수들.. |
separator
- GtkWidget* gtk_hseparator_new ()
- GtkWidget* gtk_vseparator_new ()
separator는 화면에 수평 또는 수직선을 만드는 기능을 합니다. 수평과 수직에 따라서 따로 함수가 나뉘어 지므로, 시의적절하게 사용하시면 되겠습니다.
예제는 https://developer.gnome.org/gtkmm-tutorial/stable/index.html.en 를 참고하였습니다.
해당 예제는 다음 사이트를 참고하시기 바랍니다.
https://github.com/blankspace-dev/C-/blob/master/2017/06/17/
제 글이 도움이 되셨거나 공감이 되시는 부분이 있으셨다면, 밑에 있는 공감 버튼 한 번씩 꾸욱 눌러주시면 감사하겠습니다.
공감 버튼은 저에게 큰 도움이 됩니다. 감사합니다.
- child widget는 말 그대로 상위 위젯보다 하위에 위치하는 위젯들을 말합니다 [본문으로]
'컴퓨터 관련 > Linux || Unix' 카테고리의 다른 글
[GTK+] 5. GTK+ 이벤트 (0) | 2017.06.17 |
---|---|
[GTK+] 4. GTK+ 컨테이너 Widget (2) | 2017.06.17 |
[GTK+] 2. GTK+ 기본 예제 (0) | 2017.06.12 |
[GTK+] 1. GTK+ 소개 (0) | 2017.06.11 |
[GTK+] GTK를 들어가면서 (목차) (0) | 2017.06.09 |
댓글