- 论坛徽章:
- 0
|
应用GTK+编程
使用线程
在GTK+中应用线程, 除了GLIB中的g_thread_init和g_thread_supported两个函数外,还要用到gdk_thread_init来在X WINDOW中初始化线程应用,另外在线程中要对GTK+控件进行操作时还要在操作前执行函数gdk_thread_enter来进入,操作完成后执行函数gdk_thread_leave来离开,在执行GTK+主循环时也是如此,GTK+以此来达到线程安全;下面代码利用线程创建了一个在屏幕上沿顺时针运动的图像(24x24像素):
- //thread.c
- #include <gtk/gtk.h>;
- typedef struct _Ourarg Ourarg;
- struct _Ourarg {
- GtkWidget *fixed;
- GtkWidget *image;
- gint right;
- gint left;
- };
- void image_go(Ourarg *arg)
- {
- gint x, y, toward;
- x = y = arg->;left;
- toward = 1;
- for(;;)
- {
- g_usleep(1500);
- gdk_threads_enter();
- gtk_fixed_move(GTK_FIXED(arg->;fixed),arg->;image, x, y);
- switch(toward)
- {
- case 1:
- x = x + 10;
- if( x >; arg->;right ) toward = 2;
- break;
- case 2:
- y = y + 10;
- if( y >; arg->;right ) toward = 3;
- break;
- case 3:
- x = x - 10;
- if( x < arg->;left ) toward = 4;
- break;
- case 4:
- y = y -10;
- if( y < arg->;left ) toward = 1;
- }
- gdk_threads_leave();
- }
- }
- int main(int argc, char* argv[])
- {
- GtkWidget *window;
- GtkWidget *vbox, *viewport, *button;
- GtkWidget *image, *fixed;
- Ourarg *arg;
- if(!g_thread_supported()) g_thread_init(NULL);
- gdk_threads_init();
- gtk_init(&argc,&argv);
- window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
- gtk_window_set_title(GTK_WINDOW(window),"线程测试");
- g_signal_connect(G_OBJECT(window),"delete_event",
- G_CALLBACK(gtk_main_quit),NULL);
- gtk_container_set_border_width(GTK_CONTAINER(window),2);
- vbox = gtk_vbox_new(FALSE,0);
- gtk_container_add(GTK_CONTAINER(window),vbox);
- fixed = gtk_fixed_new();
- gtk_widget_set_usize(fixed,340,340);
- viewport = gtk_viewport_new(NULL,NULL);
- gtk_box_pack_start(GTK_BOX(vbox),viewport,FALSE,FALSE,5);
- gtk_container_add(GTK_CONTAINER(viewport),fixed);
- image = gtk_image_new_from_file("ss.png");
- gtk_fixed_put(GTK_FIXED(fixed),image,40,40);
- button = gtk_button_new_with_label("退出");
- gtk_box_pack_start(GTK_BOX(vbox),button,FALSE,FALSE,5);
- g_signal_connect(G_OBJECT(button),"clicked",
- G_CALLBACK(gtk_main_quit),NULL);
- gtk_widget_show_all(window);
- arg = g_new(Ourarg,1);
- arg->;fixed = fixed;
- arg->;image = image;
- arg->;left = 40;
- arg->;right = 260;
- g_thread_create(image_go, arg, FALSE, NULL);
- gdk_threads_enter();
- gtk_main();
- gdk_threads_leave();
- return FALSE;
- }
复制代码
基于线程安全考虑,你必须将下面代码放在gtk_init函数之前执行:
[/code] if(!g_thread_supported()) g_thread_init(NULL);
gdk_threads_init();
- 结束语
- 学习GTK+的最好的方法是研究GTK+源码包中带的例程和研究其它应用GTK+的开源软件的源码包,在国内最大LINUX论坛上有很多这方面的高手。
- 如果你的英文足够好的话还可以订阅GTK+应用开发的邮件列表,这样你每天都可以收到几封关于GTK+开发的邮件,笔者最多时一天收到过近30封邮件,其中有很多人会热心的回答你的问题或帮你出主意。
- 在QT和GTK+的选择上,经常能看到一些网友的争论。对于目前国内LINUX平台上的GUI应用程序的开发,搁置争议、潜心学习、交流心得、形成合力、做出具有应用前景和自己特色的开源项目才是自由社区的当务之急。
- 注1:可以参考IBM developerWorks网站上的文章《GTK+2.0中的容器控件和布局技巧》
- 关于作者
- 宋国伟,乡村小学英语教师,他是《GTK+2.0编程范例》(清华大学出版社出版)一书的作者,业余时间致力于用GTK+开发LINUX GUI应用程序,可以通过电子邮件地址gwsong_52@sohu.com与他联系。
复制代码 |
|