2016.05.13 筆記
GTK+簡介
GTK 最初爲GIMP(一個圖像處理軟件,類似Photoshop)的工具包
後來GTK重寫爲面向對象的GTK+
GTK+ 並非是用C++寫的,而是用C語言,所謂的面向對象是用C語言模擬的。強大
GTK+ 2.0 新特性:
使用Pango(a theme engine)增強了文本渲染
improved accessibility using the Accessibility Toolkit, transition to Unicode using UTF-8 strings, and a more flexible API.GTK+ 2.8, GTK+ 2 depends on the Cairo graphics library for rendering vector graphics.
GTK+ 3.0
included revised input device handling, support for themes written with CSS-like syntax, and the ability to receive information about other opened GTK+ applications.
版本的新特性參考 wiki GTK+
編譯
GTK+ 3.0的編譯選項,用法見下文:
pkg-config --cflags gtk+-3.0
pkg-config --libs gtk+-3.0
https://developer.gnome.org/gtk3/stable/gtk-getting-started.html
fedora Linux
中安裝gtk+/gnome開發包:
dnf install gnome-devel
dnf install gtk3-devel
dnf install gtk2-devel
dnf install gtk+-devel
dnf install gcc
dnf install gcc-c++
#include <gtk/gtk.h>
void CloseRequest(GtkWidget* theWindow, gpointer data);
gint main(gint argc, gchar* argv[])
{
GtkWidget* window;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_signal_connect(GTK_OBJECT(window), "destroy",
GTK_SIGNAL_FUNC(CloseRequest), NULL);
gtk_widget_show(window);
gtk_main();
return 0;
}
void CloseRequest(GtkWidget* theWindow, gpointer data)
{
gtk_main_quit();
}
編譯:
gcc -Wall -o test01 test01.cpp `gtk-config --cflags --libs`
-Wall 輸出所有警告和錯誤
`
gtk-config`
飄號中的命令會首先執行,命令執行返回的字符串將替換到該位置,gtk-config將返回編譯選項:所需的頭文件或庫文件等信息。詳情參考Linux命令行中飄號的用法。
GLib
<glib.h>
GLib提供了一些標準的數據類型
gboolean
gpointer
gchar guchar
gint guint gshort
glong gulong
gint8 guint8 gint16
guint16 gint32 guint32
gint64 guint64
gfloat gdouble
gsize
gssize
宏
G_DIR_SEPARATOR
目錄分隔符 單個字符
G_DIR_SEPARATOR_S
0終結的串
G_SEARCHPATH_SEPARATOR
PATH 分隔符
G_SEARCHPATH_SEPARATOR_S
MIN(x, y)
MAX(x, y)
ABS()
絕對值
CLAMP(a, x, y)
g_assert()
g_print() 非調試模式可以使用g_set_print_handler()函數忽略
g_assert_not_reached() 用來定義代碼中不應該到達某個點
g_return_if_fail()
g_return_val_if_fail()
g_error() g_set_error_handler()
g_warning() g_set_warning_handler()
glib支持管理有序二叉樹、n叉樹、單向和雙向鏈表的函數
如果glib分配內存的嘗試由於某種原因未成功,則應用程序將終止
g_malloc()
g_free()
g_new(類型, 個數) g_new(char, 50)
g_realloc()
g_memdup() 自動分配一個新內存塊,然後拷貝源塊中的數據到新塊,返回新塊的指針
鏈表
單向鏈表函數名 g_slist
開頭
雙向鏈表函數名 g_list
開頭
struct GSList
{
gpointer data;
GSList* next;
}
struct GList
{
gpointer data;
GList* next;
GList* prev;
}
建立表是初始化一個表爲NULL
GList* list = NULL;
g_list_free(list)
g_slist_free()
g_list_append()
g_list_prepend()
g_list_insert(list, "data", 1); 索引從0開始,插入的位置
g_list_insert_sorted(list, "data", 比較函數)
創建窗口
X Windows System API
繼承關係
GtkObject
GtkWidget
GtkContainer
GtkBin
GtkWindow
gtk_window_new()
GTK_WINDOW_TOPLEVEL
GTK_WINDOW_DIALOG
GTK_WINDOW_POPUP
gtk_window
開頭 使用GtkWindow
gtk_widget
開頭 使用GtkWidget
gtk_main()
啓動GTK+循環
事件和信號
X本身能夠抓住所產生的某些事情,如窗口刪除、點擊按鈕等,這些都爲信號。
GTK+還添加了自己的特定類型,爲事件
在代碼中使用信號和事件沒有區別。
信號連接
gtk_signal_connect(GTK_OBJECT(theWindow), "destroy",
GTK_SIGNAL_FUNC(StopTheApp), NULL);
GTK_OBJECT
將theWindow
轉換爲基類對象GtkObject
因爲信號處理程序的聲明不一樣,所以GTK_SIGNAL_FUNC
轉換
編寫信號處理程序時,需要查詢信號文檔以便知道處理函數應有的格式。
參考 GTK+/GNOME程序設計
附錄A
信號處理程序是事後調用的。這樣,一個窗口取消並且在其取消後調用信號處理程序。
事件是事前產生的。因此,每個窗口有一個稱爲delete_event
的事件,該事件在窗口取消前產生。
事件處理程序中:
return TRUE
告訴GTK+我處理了此事件
return FALSE
告訴GTK+我不處理這個事件,你來處理
比如在delete_event
處理程序中返回TRUE
以禁止GTK+取消窗口
連接事件只需將"destroy"
改爲"delete_event"
GdkEvent
參考第三章
GdkEventType
事件類型 “event” 捕獲所有事件
gint gtk_signal_connect()
返回處理程序ID
斷開信號處理程序的連接
gtk_signal_disconnect(GTK_OBJECT(myWindow), id);
不使用ID斷開連接:
gtk_signal_disconnect_by_func()
設置窗口標題
gtk_window_set_title(GTK_WINDOW(myWindow), "This is the caption");
gtk_window_set_default_size(GTK_WINDOW(myWindow), 640, 480);
gtk_window_set_position()
GTK_WIN_POS_NONE GTK+將窗口放在它想放置的位置,默認
GTK_WIN_POS_CENTER 屏幕居中
GTK_WIN_POS_MOUSE 窗口中心和鼠標點相同
gtk_widget_set_uposition()
GTK+的按鈕實際上是一個容器,包含一個文本標籤
將小部件添加到容器的步驟:
- 建立需要添加的窗口小部件
- 將其添加到容器中
- 設置其信號和事件的回調機制
- 顯示這個窗口小部件
GtkWidget* AddButton(GtkWidget* theWindow, const gchar* buttonText)
{
GtkWidget* button;
button = gtk_button_new_with_label(buttonText);
gtk_container_add(GTK_CONTAINER(theWindow), button);
gtk_widget_show(button);
return button;
}
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(ButtonClicked), NULL);
gtk_container_border_width(GTK_CONTAINER(window), 5);
佈局
GtkBox GtkHBox GtkVBox
gtk_hbox_new()
gtk_box_pack_start()
gtk_box_pack_end()
包裝框添加小部件的步驟:
- 建立窗口小部件
- 將它添加到包裝框中
- 顯示它
/* 示例 */
GtkWidget* box;
box = gtk_hbox_new(TRUE, 5); // homogenous 均勻的 第二個參數,小部件間的間距
button = gtk_button_new_with_label(...);
gtk_box_pack_start(GTK_BOX(box), button,
FALSE, TRUE, 0); // expand fill padding
gtk_widget_show(button);
gtk_widget_show(box);
最好建立了窗口的所有內容並準備顯示時再顯示此窗口。否則在速度慢的機器上用戶會看到窗口和用戶界面一點一點建立的過程。
GtkRequisition
gint16 width
gint16 height
GtkAllocation
gint16 x
gint16 y
guint16 width
guint16 height
gtk_widget_show_all()
可以一次顯示所有的窗口小部件
包裝表 GtkTable
gtk_table_new(guint rows, guint columns, gboolean homogenous)
homogenous
TRUE
所有列使用表中最大窗口小部件的寬度,行同理
將窗口小部件添加到表中:
gtk_table_attach_defaults(..., guint left_attach, guint right_attach, ...)
left_attach 0 right_attach 1
表示小部件放在第一列,0 2 表示 橫跨1 2兩列
defaults
表示 expand fill padding
爲默認 TRUE TRUE 0
gtk_table_attach()
GtkAttachOptions
GTK_EXPAND GTK_FILL
窗口小部件 GtkLabel
gtk_label_new(const gchar* str)
gtk_label_set_text(..., const gchar* str) 空指針表示清除文本
gtk_label_set_line_wrap() 使文本超過寬度自動換行
gtk_label_set_justify() 總是垂直居中,無法控制,不能在運行中改變對齊方式,必須在顯示前設置
GtkJustification
GTK_JUSTIFY_LEFT GTK_JUSTIFY_FIGHT GTK_JUSTIFY_CENTER GTK_JUSTIFY_FULL
GtkEntry 文本輸入框
gtk_entry_new(void)
gtk_entry_new_width_max_length(guint16 max) // 限制字符數
gtk_entry_set_max_length()
gtk_entry_get_text()
gtk_entry_set_text()
gtk_entry_set_visibility(..., gboolean visible) // false 用星號顯示,無法定製使用其他符號
gtk_entry_prepend_text() // 將文本插入到已有文本前面
gtk_entry_append_text()
GtkEditable
GtkEditable
是GtkEntry
的基類
gtk_editable_set_editable()
gtk_editable_select_region() 高亮選中文本 [start, end) MAXINT
剪貼板函數,對選中的文本進行操作
gtk_editable_cut_clipboard()
gtk_editable_copy_clipboard()
gtk_editable_paste_clipboard()
GtkToggleButton
GtkToggleButton
派生於 GtkButton
“toggled” “clicked”
gtk_toggle_button_new_with_label("Toggle Me")
gtk_toggle_button_new()
gtk_toggle_button_get_active()
gtk_toggle_button_set_active()
gtk_toggle_button_toggled()
GtkCheckButton
窗口小部件的外觀取決於所使用的窗口管理器,它負責窗口小部件的繪製。
gtk_check_button_new_with_label()
gtk_check_button_new()
GtkRadioButton
GtkRadioButton
派生於 GtkCheckButton
步驟:
- 建立一個空的GList指針(單向鏈表)
- 將列表傳遞給建立單選鈕的函數
- 將單選鈕添加到容器中
- 顯示單選鈕
- 得到從單選鈕中返回的更改過的鏈表
GSList* group = NULL;
GtkWidget* radio;
radio = gtk_radio_button_new_with_label(group, "Some Text");
group = gtk_radio_button_group(radio);
GtkFrame
GtkFrame
一個可視容器,如同窗口一樣只能擁有一個窗口小部件,所以,先將一個Box添加到Frame上
gtk_frame_set_label_align(..., gfloat xalign, yalign) 0 - 1,標題的顯示位置
gtk_frame_set_shadow_type()
GtkShadowType
GTK_SHADOW
GTK_SHADOW_IN
GTK_SHADOW_OUT
GTK_SHADOW_ETCHED_IN
GTK_SHADOW_ETCHED_OUT
GtkList 基本的列表框
GtkCList GtkList
GtkList 是一個容器,可將各種窗口小部件添加到此列表中,GtkListItem
GtkListItem也是容器,沒有標籤的可以將任意窗口小部件按鈕或像素映射圖加到其中
gtk_list_new()
gtk_list_item_new_with_label()
gtk_container_add(GTK_CONTAINER(listbox), listitem)
gtk_widget_show(listitem)
使用列表
memeroylist = g_list_append(memorylist, listitem)
gtk_list_append_items(GTK_LIST(listbox), memorylist)
gtk_list_set_selection_mode(GTK_LIST(list), GTK_SELECTION_EXTENDED);
連接信號
gtk_signal_connect(GTK_OBJECT(list), "select_child", ...)
gtk_signal_connect(GTK_OBJECT(list), "unselect_child", ...)
void ItemPrinter(gpointer data, gpointer userdata)
{
// data - list item
}
g_list_foreach(list, ItemPrinter, NULL);
GtkCombo
struct GtkCombo
{
Gtk_HBox hbox;
GtkWidget* entry;
GtkWidget* button;
GtkWidget* popup;
GtkWidget* popwin;
GtkWidget* list;
}
gtk_combo_new()
GList* options = NULL;
options = g_list_append(options, "Male");
options = g_list_append(options, "Female");
options = g_list_append(options, "Other");
gtk_combo_set_popdown_strings(GTK_COMBO(mycombo), options);
獲取當前項文本:
gchar* selectedValue;
selectedValue = gtk_enty_get_text(
GTK_ENTRY(GTK_COMBO(combo)->entry));
GtkCList 多列列表
gtk_clist_new()
gtk_clist_new_with_titles()
gtk_clist_column_titles_show()
gtk_clist_column_tities_hide()
gtk_clist_column_title_active() // 使指定列標題按鈕可點擊
gtk_clist_column_title_passive()
gtk_clist_column_titles_active()
gtk_clist_column_titles_passive()
gtk_clist_set_column_width()
gtk_clist_set_row_height()
gtk_clist_prepend(..., gchar* text[]);
gtk_clist_append()
gtk_clist_insert()
gtk_clist_remove(..., gint row)
gtk_clist_clear()
gtk_clist_freeze() // 更改列表時不刷新,避免閃爍
gtk_clist_thaw()
gtk_clist_set_text()
gtk_clist_get_text()
gtk_clist_set_pixmap()
gtk_clist_set_pixtext()
gtk_clist_select_row()
gtk_clist_unselect_row()
gtk_clist_get_selection_info() // 利用座標所對應的行和列更新row column參數
事件
select_row
unselect_row
對話框
gtk_window_new(GTK_WINDOW_DIALOG); // 沒有最大化圖標
gtk_window_set_modal(..., gboolean modal) // 模態對話框
gtk_widget_destroy() // destroy信號
gtk_widget_hide() // hide信號
gtk_hseparator_new() // GtkHSeparator 分隔控件
gtk_main() gtk_main_quit()可以嵌套調用
GtkDialog 內建包裝框
vbox
action_area
GtkFileSelection
文件列表、目錄列表、目錄選擇按鈕、錄入框(顯示文件過濾器和所選文件名)
gtk_file_selection_new()
gtk_widget_show()
gtk_file_selection_set_filename() // 提供缺省文件名
gtk_file_selection_show_fileop_buttons()
gtk_file_selection_hide_fileop_buttons()
gtk_file_selection_complete() // 希望設置的過濾器的串的指針
ok_button 成員
cancel_button 成員
gtk_signal_connect(GTK_OBJECT(GTK_FILE_SELECTION(filedialog)->ok_button), ...)
gtk_file_selection_get_filename() // 絕對路徑文件名
GtkColorSelectionDialog
核心小部件 GtkColorSelection
重要成員:
colorsel
ok_button
reset_button
cancel_button
help_button
gdouble selectedcolor;
gtk_color_selection_get_color(GTK_COLOR_SELECTION(
GTK_COLOR_SELECTION_DIALOG(theDialog)->colorsel), & selectedcolor);
待續…