- 浏览: 454795 次
- 性别:
- 来自: 深圳
文章分类
最新评论
-
zjhgx:
多谢,多谢。多谢
Ubuntu 中软件的安装、卸载以及查看的方法总结 -
37du:
受教了,对于理解运行过程有很好的效果
ActionMapper---webwork 2.1到2.2 的变化 -
chxiaowu:
非常好,谢谢!
Ubuntu 中软件的安装、卸载以及查看的方法总结 -
euii:
谢谢,这样的总结。
Ubuntu 中软件的安装、卸载以及查看的方法总结 -
xiaoyao3857:
谢谢,正需要这样的汇总型字典!
Ubuntu 中软件的安装、卸载以及查看的方法总结
在我们教程的这一个章节中,我们会谈一谈GTK+函数工具库中的,“事件”系统 。
GTK+函数工具库是基于 “事件” 系统的。所有的 GUI 应用程序无一例外都是基于“事件”驱动的。假如没有“事件”发生,则应用程序就什么都不会做。在GTK+中一个事件就是从X窗口服务器传出来的一个消息。 当一个“事件”发生时,他就会通过发送一个“信号”来表示他已经做出了反应。利用GTK+还可以为“信号”绑定专门的回调函数。也就是说回调函数只对他特 定的“信号”才有反应并执行。
#include <gtk/gtk.h> void button_clicked(GtkWidget *widget, gpointer data) { g_print("clicked\n"); } int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *fixed; GtkWidget *button; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "GtkButton"); gtk_window_set_default_size(GTK_WINDOW(window), 230, 150); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); fixed = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), fixed); button = gtk_button_new_with_label("Click"); gtk_fixed_put(GTK_FIXED(fixed), button, 50, 50); gtk_widget_set_size_request(button, 80, 35); g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), NULL); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
在我们上面的这个示例应用程序中,我们有两个“信号”。一个是信号clicked ,也就是单击;另外则是信号 destroy 。
g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), NULL)
我们用函数 g_signal_connect() 去“连接”信号“clicked”和回调函button_clicked() 。
void button_clicked(GtkWidget *widget, gpointer data) { g_print("clicked\n"); }
这个回调函数执行的功能是向终端输出“clicked”字符串。这个函数的第一行参就是那个发射信号的对象。在我们的这个例子中实参便是构件“Click button”。第二个行参是可以选择有无的。我们可以利用这个参数向回调函数传递特定的数据。在我们的例子中,并没有传递任何的参数。所以我们就在 g_signal_connect()中调用回调函数的时候在调用的第二个实参中填上了“NULL”。
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL);
如果我们单击窗口右上角的“X”或者按Atl + F4, 一个destroy 就被发射出去了。然后呢,我们为这个信号所绑定的回调函数gtk_main_quit() 将执行,他的功能是终止整个应用程序。
移动窗口(Moving window)
在下一个例子中,我们将展示是如何对“移动窗口”这个事件做出反应的。
#include <gtk/gtk.h> void frame_callback(GtkWindow *window, GdkEvent *event, gpointer data) { int x, y; char buf[10]; x = event->configure.x; y = event->configure.y; sprintf(buf, "%d, %d", x, y); gtk_window_set_title(window, buf); } int main(int argc, char *argv[]) { GtkWidget *window; 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, 150); gtk_window_set_title(GTK_WINDOW(window), "Simple"); gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); g_signal_connect(G_OBJECT(window), "configure-event", G_CALLBACK(frame_callback), NULL); gtk_widget_show(window); gtk_main(); return 0; }
在这个例子中,我们随时追踪显示了位于左上角的标题栏的位置。
gtk_widget_add_events(GTK_WIDGET(window), GDK_CONFIGURE);
上面这行代码说明了,哪一个构件将回接受到事件,并对事件的发生做出反应。一些事件使用时要已与特定的构件组装好了,另外的一些事件不得不要用一个函数 gtk_widget_add_events() 去武装他。把事件类型GDK_CONFIGURE 填加到这个函数中。事件类型GDK_CONFIGURE 包含了所有的大小、位置和用于存储事件次序的栈结构。
g_signal_connect(G_OBJECT(window), "configure-event", G_CALLBACK(frame_callback), NULL);
从上面可以看出,信号“ configure-event “被发射了 ,则所绑定构件的大小、位置与次序栈都被捕获了。
void frame_callback(GtkWindow *window, GdkEvent *event, gpointer data) { int x, y; char buf[10]; x = event->configure.x; y = event->configure.y; sprintf(buf, "%d, %d", x, y); gtk_window_set_title(window, buf); }
这个回调函数有三个行参。分别是:反射信号的构件, GdkEvent 和可选择的行参.。我们获取了位置坐标(x,y),并把他放在了标题栏上。
鼠标进入信号(The enter signal)
在接下来的章节中,我们将展示如何对“鼠标的进入 ”信号作出反应。当我们的鼠标移动到我们所绑定的那个构件上时就会发出“鼠标进入信号”。
#include <gtk/gtk.h> void enter_button(GtkWidget *widget, gpointer data) { GdkColor color; color.red = 27000; color.green = 30325; color.blue = 34181; gtk_widget_modify_bg(widget, GTK_STATE_PRELIGHT, &color); } int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *fixed; GtkWidget *button; 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, 150); gtk_window_set_title(GTK_WINDOW(window), "enter signal"); fixed = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), fixed); button = gtk_button_new_with_label("Button"); gtk_widget_set_size_request(button, 80, 35); gtk_fixed_put(GTK_FIXED(fixed), button, 50, 50); g_signal_connect(G_OBJECT(button), "enter", G_CALLBACK(enter_button), NULL); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
上面的程序想实现这样的一个功能:当我们的鼠标掠过按钮构件的时候,我们的程序代码可以改变那个按钮的背景颜色。
g_signal_connect(G_OBJECT(button), "enter", G_CALLBACK(enter_button), NULL);
当信号“enter ”发生时,我们会调用函数 enter_button()
GdkColor color; color.red = 27000; color.green = 30325; color.blue = 34181; gtk_widget_modify_bg(widget, GTK_STATE_PRELIGHT, &color);
在对应的回调函数中,我们通过调用函数gtk_widget_modify_bg() 来改变按钮的颜色。
回调函数解除绑定(Disconnecting a callback)
既然可以为一个信号绑定一个回调函数,我们当然也可以解除一个绑定。在接下来的代码示范示例中就是这样的一个例子。
#include <gtk/gtk.h> int handler_id; void button_clicked(GtkWidget *widget, gpointer data) { g_print("clicked\n"); } void toogle_signal(GtkWidget *widget, gpointer window) { if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { handler_id = g_signal_connect(G_OBJECT(window), "clicked", G_CALLBACK(button_clicked), NULL); } else { g_signal_handler_disconnect(window, handler_id); } } int main( int argc, char *argv[]) { GtkWidget *window; GtkWidget *fixed; GtkWidget *button; GtkWidget *check; 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), 250, 150); gtk_window_set_title(GTK_WINDOW(window), "Disconnect"); fixed = gtk_fixed_new(); gtk_container_add(GTK_CONTAINER(window), fixed); button = gtk_button_new_with_label("Click"); gtk_widget_set_size_request(button, 80, 30); gtk_fixed_put(GTK_FIXED(fixed), button, 30, 50); check = gtk_check_button_new_with_label("Connect"); gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), TRUE); gtk_fixed_put(GTK_FIXED(fixed), check, 130, 50); handler_id = g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), NULL); g_signal_connect(G_OBJECT(check), "clicked", G_CALLBACK(toogle_signal), (gpointer) button); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_widget_show_all(window); gtk_main(); return 0; }
在例子中,我们生成了一个按钮和一个选择框。那个选择框的功能便是绑定或者解除绑定一个回调函数与信号“clicked”之间的关系。
handler_id = g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(button_clicked), NULL);
g_signal_connect() 函数执行后会返回一个“id”数据。这就是实现了对回调函数的唯一标示。
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) { handler_id = g_signal_connect(G_OBJECT(window), "clicked", G_CALLBACK(button_clicked), NULL); } else { g_signal_handler_disconnect(window, handler_id); }
这段代码决定了选择框的状态,如果选中了,就绑定否则就解除绑定。
(拖与放的示例)Drag and Drop example
在接下一个示例中,我们将展示一个有趣的特性。我们将生成一个没有边框的窗口,然后我们将说明如何才能拖动和放置这样的一个窗口。
#include <gtk/gtk.h> gboolean on_button_press (GtkWidget* widget, GdkEventButton * event, GdkWindowEdge edge) { if (event->type == GDK_BUTTON_PRESS) { if (event->button == 1) { gtk_window_begin_move_drag(GTK_WINDOW(gtk_widget_get_toplevel(widget)), event->button, event->x_root, event->y_root, event->time); } } return FALSE; } int main( int argc, char *argv[]) { GtkWidget *window; 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, 150); gtk_window_set_title(GTK_WINDOW(window), "Drag & drop"); gtk_window_set_decorated(GTK_WINDOW (window), FALSE); gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK); g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(on_button_press), NULL); g_signal_connect_swapped(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), G_OBJECT(window)); gtk_widget_show(window); gtk_main(); return 0; }
上面的这个示例程序向我们展示了如何才能生成一个可以拖拉和放置的无边框的窗口程序。
gtk_window_set_decorated(GTK_WINDOW (window), FALSE);
我们去除了窗口中的一些修饰性的部分。也就是说我们的这个窗口没有边框和标题栏。
g_signal_connect(G_OBJECT(window), "button-press-event", G_CALLBACK(on_button_press), NULL);
我们把信号button-press-event 绑定在窗口中。
gboolean on_button_press (GtkWidget* widget, GdkEventButton * event, GdkWindowEdge edge) { if (event->type == GDK_BUTTON_PRESS) { if (event->button == 1) { gtk_window_begin_move_drag(GTK_WINDOW(gtk_widget_get_toplevel(widget)), event->button, event->x_root, event->y_root, event->time); } } return FALSE; }
在回调函数on_button_press() 中,我们放置了拖动和放置的代码。 我们检测是否鼠标被单击(左击)。然后条件判断执行函数 gtk_window_begin_move_drag() 进行拖放操作。
(一个定时器) A timer example
在接下来的示例中我们将向你展示如何去生成一个定时器。定时器通常应用于当我们要做一些重复工作的场合。譬如一个时钟,一个倒记时和增加动态的视觉效应。
#include <cairo.h> #include <gtk/gtk.h> #include <time.h> static char buffer[256]; static gboolean on_expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { cairo_t *cr; cr = gdk_cairo_create(widget->window); cairo_move_to(cr, 30, 30); cairo_show_text(cr, buffer); cairo_destroy(cr); return FALSE; } static gboolean time_handler(GtkWidget *widget) { if (widget->window == NULL) return FALSE; time_t curtime; struct tm *loctime; curtime = time(NULL); loctime = localtime(&curtime); strftime(buffer, 256, "%T", loctime); gtk_widget_queue_draw(widget); return TRUE; } int main (int argc, char *argv[]) { GtkWidget *window; GtkWidget *darea; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); darea = gtk_drawing_area_new(); gtk_container_add(GTK_CONTAINER (window), darea); g_signal_connect(darea, "expose-event", G_CALLBACK(on_expose_event), NULL); g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 170, 100); gtk_window_set_title(GTK_WINDOW(window), "timer"); g_timeout_add(1000, (GSourceFunc) time_handler, (gpointer) window); gtk_widget_show_all(window); time_handler(window); gtk_main(); return 0; }
我们将要在窗口中,“画”一个显示当前时间的动态效果。所用的工具,就是在我们一开始曾经提到过的Cairo函数工具库。
g_signal_connect(darea, "expose-event", G_CALLBACK(on_expose_event), NULL);
首先我们要把在回调函数 on_expose_event() 中画出时间的数值。这个回调函数与信号进行了绑定expose-event 。如果这个信号发射出去了,这个窗口就会按照我们程序所安排的一样——“立即刷新”。
g_timeout_add(1000, (GSourceFunc) time_handler, (gpointer) window);
上面的这个函数注册了一个GTK+系统中的一个定时器(是抽象的不可见的)。函数 time_handler() 就会被按照我们在函数中的设置在设定的时间内不断的运行。在例子中,我们设定了这个时间为1秒,一旦这个函数 g_timeout_add() 返回FALSE,定时器函数 time_handler() 就会运行。
time_handler(window);
这行代码的作用是立即启动定时器,否则的话,你会看到1秒的延迟。
cairo_t *cr; cr = gdk_cairo_create(widget->window); cairo_move_to(cr, 30, 30); cairo_show_text(cr, buffer); cairo_destroy(cr);
以上便是用来在当前窗口上画出当前时间的代码。如果你想了解更多的关于Cairo函数库的一些情况请访问 版权属于ZetCode。. .
if (widget->window == NULL) return FALSE;
在我们刷新窗口前,很显然要先注销窗口,这样的话,定时函数便被自动调用了;可当我们关闭窗口时,定时器也会被调用,这是我们不想看到了,所以需要加上以上的代码,阻止在已经关闭的构件上运行定时器。
time_t curtime; struct tm *loctime; curtime = time(NULL); loctime = localtime(&curtime); strftime(buffer, 256, "%T", loctime);
上面的代码获取了系统当前的时间。
gtk_widget_queue_draw(widget);
这段代码会注销窗口,然后信号 expose-event 就会被激活发射出去。从而被绑定的回调函数就会执行。
发表评论
-
htonl(),htons(),ntohl(),ntons()--大小端模式转换函数
2010-12-16 16:51 4169不同机器内部对变量的字节存储顺序不同,有的采用大端模式(big ... -
关于Linux静态库和动态库的分析
2010-09-28 10:29 16651.什么是库在windows平台和linux平台下都大量存在着 ... -
Heartbeat
2010-09-01 19:31 1426Heartbeat 项目是 Linux-HA ... -
linux下更改共享内存的最大值
2010-07-26 13:22 6100System V IPC 参数 名字 ... -
环境变量相关
2010-06-10 15:03 1030系统环境变量: /etc/profile:此文件 ... -
linux中的信号处理(signal与alarm)
2010-05-12 15:25 1813简单处理程序: ... -
LINUX 时间和日期
2010-04-01 19:09 2593时间与日期 通常对于 一个程序来说可以确定时间与日期是十分 ... -
IPC之消息队列
2010-03-13 12:05 1453消息队列缺点: 1. 如果进程创建了一个消息队列,在该队 ... -
如何让errno多线程/进程安全
2010-03-13 11:35 1808在 linux 或者 unix 环境中, errno ... -
Linux下库相关的概略介绍及动态库的搜索路径优先级
2010-03-13 11:29 1682(本文主要针对动态连接 ... -
ftok函数
2010-03-13 11:01 1805系统建立IPC通讯(如消 ... -
About pci.ids
2009-12-23 21:01 1788pci.ids - This is a public r ... -
port I/O
2009-12-21 15:27 1245Name outb, outw, outl, outsb ... -
udev相关
2009-12-11 20:22 1217udev 是Linux kernel 2.6系 ... -
SMP(Symmetrical Multi-Processing)
2009-12-11 15:22 1781对称多处理" ... -
功能强大的sed命令
2009-11-27 21:55 2054vim不太熟练,发现shell的sed命令很强大。 1. S ... -
/etc/sudoers配置文件的格式
2009-11-25 20:56 1680-------下面文章转载自网 ... -
/etc/sudoers中的含义
2009-11-25 20:55 2572Sudo 是允许系统管理员让普通用户执行一些或者全部的roo ... -
linux下如何模拟按键输入和模拟鼠标
2009-11-14 10:06 2864查看/dev/input/eventX是什么类型的事件, ca ... -
Linux root file system
2009-11-05 20:03 11091. Linux for PowerPC Embedded S ...
相关推荐
5. **信号与回调**:深入解析 GTK+ 的事件处理机制,包括信号的定义、连接回调函数,以及如何响应用户的交互操作。 6. **主题与国际化**:讨论 GTK+ 的主题引擎,允许开发者自定义界面外观,以及支持多语言的机制,...
GTK+ 程序设计中文版 ...在 Linux 系统中,GTK+ 是一个非常流行的 GUI 开发工具包,许多知名的桌面环境和应用程序都是使用 GTK+ 构建的。了解 GTK+ 的使用和应用将有助于您更好地开发图形交互界面应用程序。
在Gtk+ 3.6.4中,它引入了许多新特性、改进和优化,旨在提升用户体验和开发者的工作效率。 1. 主要特性: - 多平台支持:Gtk+不仅仅限于Linux,还包括Windows和Mac OS X。 - 完善的主题引擎:允许自定义界面外观...
这份文档是学习和开发GTK+3.0应用的宝贵资源,它涵盖了所有关键概念、控件和函数,帮助开发者从基础到高级逐步掌握GTK+3.0。在实际项目中,结合文档和实践,开发者可以构建出高效、美观的跨平台应用程序。
GTK+ 参考手册 for GTK+ 2.14.3,最新英文版 GTK+ is a library for creating graphical user interfaces. It works on many UNIX-like platforms, Windows, and on framebuffer devices. GTK+ is released under ...
GTK+提供了用于构建GUI应用程序的各种控件、布局管理和事件处理机制。开发者可以使用C语言来编写GTK+应用,也可以通过绑定到其他语言,如Python、Perl或Vala来使用。 3. **gettext-0.18.1.1.tar.gz**:这是一个用于...
这个“gtk+-bundle_2.24.10-20120208_win32.zip”文件是一个针对Windows 32位系统的GTK+ 2.24.10版本的打包下载,包含了开发GTK+应用所需的所有组件和库。这个压缩包主要是为了方便Windows开发者在没有原生支持的...
4. **事件处理**:通过GTK+的信号和回调机制,当用户在界面上进行操作时,如点击按钮或选择菜单项,相应地执行相应的业务逻辑。 5. **错误处理和调试**:为确保程序的稳定性和用户体验,添加错误处理代码,对可能...
GTK+2.0编程范例-书籍和书中代码.tar.gz 是一个包含有关GTK+2.0编程的资源压缩包,适合初学者和希望提升技能的开发者。GTK+ 是一款广泛使用的开源图形用户界面(GUI)工具包,尤其在Linux和其他类UNIX系统中应用广泛...
3. **信号与回调**:阐述GTK+中的事件处理机制,如何通过连接信号和回调函数响应用户操作。 4. **布局管理**:讲解如何使用Grid、Box、Table等布局管理器来组织控件,实现复杂的界面布局。 5. **主题与样式**:...
1. Hello World 程序:介绍如何编写一个简单的 GTK+ 程序,包括信号和回调函数的使用。 2. 数据类型:介绍 GTK+ 中的数据类型,包括整数、浮点数、字符串等。 3. 信号处理函数:介绍如何使用信号处理函数来响应用户...
介绍信号和回调函数的概念,这是GTK+事件处理的基础。 4. **创建第一个GTK+程序**:逐步指导编写一个简单的“Hello, World”程序,让读者了解GTK+程序的基本结构。 5. **布局管理**:讲述如何使用盒式布局(Box)...
它包含了一整套开发和运行GTK+应用程序所需的所有组件,使得开发者能够在Windows环境下开发和运行基于GTK+的应用程序。 GTK+ 是开源的,由GNOME项目维护,最初是为了支持GIMP图像编辑器而设计的。它支持多种编程...
值得注意的是,它特别强调了GTK+ 3.x版本与Python 2.7的不兼容性,意味着如果你计划在Python环境中使用GTK库,应当确保安装的是GTK+ 2.x版本。 GTK+ 2.x系列是该库的一个较早版本,它支持多种编程语言,包括C、C++...
在GTK+中,事件处理机制基于信号和槽的概念。当用户与界面交互时,会产生各种信号(如点击按钮),这些信号可以连接到指定的槽函数上,从而实现特定的功能响应。 ##### 4.3 布局管理器 为了使用户界面适应不同的...
虽然信号和事件在某种程度上看起来相似,但它们有着本质的区别。在 GTK+ 中,事件主要指的是底层窗口系统发送的消息,如鼠标移动、键盘按键等。而信号则是一种更高层次的概念,它是基于事件之上的一种机制,用于处理...
根据给定的信息,我们可以推断出《用GTK+和GDK开发Linux图形用户界面应用》是一本专注于使用GTK+和GDK在Linux环境下构建GUI应用程序的专业书籍。虽然提供的部分内容并没有直接涉及具体的技术细节,但我们可以结合...
GTK+是一个用C语言编写的开源GUI库,它提供了丰富的控件和事件处理机制,而Glade则是一个设计工具,用于帮助开发者创建GTK+应用程序的用户界面。 GTK+(GIMP Toolkit)起源于GIMP图像编辑器的开发,后来发展成为一...
这个过程涉及到安装GTK+库,配置编译器路径,设置项目属性,以及可能的链接器选项,以确保在Visual Studio 2008中能够顺利编译和运行使用GTK+的C或C++程序。 描述中提到的“gtk+-bundle_2.24.10-20120208_win32文件...