gtk
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
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();
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
编译:
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
宏
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()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
如果glib分配内存的尝试由于某种原因未成功,则应用程序将终止
g_malloc()
g_free()
g_new(类型, 个数) g_new(char, 50)
g_realloc()
g_memdup() 自动分配一个新内存块,然后拷贝源块中的数据到新块,返回新块的指针
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
链表
单向链表函数名 g_slist
开头
双向链表函数名 g_list
开头
struct GSList
{
gpointer data;
GSList* next;
}
struct GList
{
gpointer data;
GList* next;
GList* prev;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
建立表是初始化一个表为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", 比较函数)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
创建窗口
X windows System API
继承关系
GtkObject
GtkWidget
Gtkcontainer
GtkBin
GtkWindow
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
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);
- 1
- 2
- 1
- 2
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 窗口中心和鼠标点相同
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
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;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
gtk_signal_connect(GTK_OBJECT(button), "clicked",
GTK_SIGNAL_FUNC(ButtonClicked), NULL);
gtk_container_border_width(GTK_CONTAINER(window), 5);
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
布局
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);
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
最好建立了窗口的所有内容并准备显示时再显示此窗口。否则在速度慢的机器上用户会看到窗口和用户界面一点一点建立的过程。
GtkRequisition
gint16 width
gint16 height
GtkAllocation
gint16 x
gint16 y
guint16 width
guint16 height
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
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
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
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()
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
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()
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
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()
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
GtkCheckButton
窗口小部件的外观取决于所使用的窗口管理器,它负责窗口小部件的绘制。
gtk_check_button_new_with_label()
gtk_check_button_new()
- 1
- 2
- 1
- 2
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);
- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
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", ...)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
void ItemPrinter(gpointer data, gpointer userdata)
{
// data - list item
}
g_list_foreach(list, ItemPrinter, NULL);
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
GtkCombo
struct GtkCombo
{
Gtk_HBox hbox;
GtkWidget* entry;
GtkWidget* button;
GtkWidget* popup;
GtkWidget* popwin;
GtkWidget* list;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
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));
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
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参数
- 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
- 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
事件
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()可以嵌套调用
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
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() // 绝对路径文件名
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
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);
- 1
- 2
- 3
- 1
- 2
- 3
待续…