GTK线程的简单使用与线程中更新图形界面

GTK线程的简单使用与线程中更新图形界面

 

1)线程的简单使用,通过一个简单例子来说明(能运行)

 

编译命令:
gcc   `pkg-config gtk+-2.0 --cflags --libs gthread-2.0` -std=gnu99  -o thread  thread.c
注意要加上gthread-2.0

 

 

#include <gtk/gtk.h>

GtkWidget *window;
GtkWidget *label;

void hello(){
	int i;
	for(i=0;;i++){
		/*使用gdk_thread_*()将要刷新的界面*/
		char buf[6];
		sprintf(buf,"%d",(int)i);
		/*睡眠一下*/
		sleep(1);
		gdk_threads_enter();
		gtk_label_set_text(GTK_LABEL(label),buf);
		gdk_threads_leave();
		if(i==100)i=0;
	}
}

int main( int   argc,char *argv[] ){
	gtk_init (NULL,NULL);//这个函数这样使用不好,但在此例中简写它了
	/* 创建一个新窗口 */
	window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(window),"thread number");
	gtk_widget_set_usize(GTK_WIDGET(window),200,60);
	/*创建一个标签*/
	label=gtk_label_new("0");
	gtk_container_add (GTK_CONTAINER (window), label);
	gtk_widget_show (label);
	gtk_widget_show (window);
	g_signal_connect (G_OBJECT (window), "destroy",G_CALLBACK(gtk_main_quit), NULL);
	
	/*线程的初始化*/
	if(!g_thread_supported()) g_thread_init(NULL);
	gdk_threads_init();
	/*创建线程*/
	g_thread_create((GThreadFunc)hello, NULL, FALSE, NULL);
	
	gdk_threads_enter();
	gtk_main ();
	gdk_threads_leave();   
	
	return 0;
}

 

 

 

2)线程中更新图形界面的方法:
要在GTK的线程中更新图形界面,则需要调用gdk_threads_enter();与gdk_threads_leave();将要更新图形界面的地方前后包围起来,
如:

 

gdk_threads_enter();
gtk_clist_append(GTK_CLIST(user_clist), text);
gdk_threads_leave();

 

gdk_threads_*()的作用并不是进入线程,据网上说是线程同步用的。
但一定要将要更新的部位包裹住,有多少个地方需要更新界面,就用多少次gdk_threads_*(),将其包裹住,
如有线程函数:

 

void  Thread(){
……
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL(label),"hello1.");
gdk_threads_leave();
……
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL(label),"hello2.");
gdk_threads_leave();
……
gdk_threads_enter();
gtk_label_set_text(GTK_LABEL(label),"hello2.");
gdk_threads_leave();
……
}

 

(我就是在这弄了好久,才发现原来是要包裹住要更新的控件,不能加入其它别的代码才行)

 

以上是个人的一点小见解,若文中有错误,请大家多多提出意见,我会尽快改正。

 

 

 

 

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我会尽力回答你的问题。以下是一个简单的 Linux 图形界面编程的教程,包含一个计算器的源代码。 1. 安装 GTK+ 库 GTK+ 是 Linux 下常用的 GUI 库,可以通过以下命令安装: ```bash sudo apt-get install libgtk-3-dev ``` 2. 创建 GUI 窗口 下面是一个简单的创建 GUI 窗口的代码: ```c #include <gtk/gtk.h> int main(int argc, char *argv[]) { GtkWidget *window; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Calculator"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 230, 250); gtk_container_set_border_width(GTK_CONTAINER(window), 10); gtk_widget_show(window); gtk_main(); return 0; } ``` 这段代码创建了一个名为 "Calculator" 的窗口,并设置了窗口的位置、大小和边框宽度。需要注意的是,最后一行代码 `gtk_main()` 是一个循环,它会一直运行直到程序退出,因为 GTK+ 是基于事件驱动的。 3. 添加按钮和文本框 我们需要在窗口中添加按钮和文本框,用于实现计算器的功能。下面是一个添加按钮和文本框的代码: ```c #include <gtk/gtk.h> void button_clicked(GtkWidget *button, gpointer data) { g_print("Button clicked\n"); } int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *grid; GtkWidget *button; GtkWidget *entry; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Calculator"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 230, 250); gtk_container_set_border_width(GTK_CONTAINER(window), 10); grid = gtk_grid_new(); gtk_container_add(GTK_CONTAINER(window), grid); entry = gtk_entry_new(); gtk_entry_set_alignment(GTK_ENTRY(entry), 1); gtk_widget_set_size_request(entry, 200, 30); gtk_grid_attach(GTK_GRID(grid), entry, 0, 0, 4, 1); button = gtk_button_new_with_label("7"); g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), NULL); gtk_grid_attach(GTK_GRID(grid), button, 0, 1, 1, 1); button = gtk_button_new_with_label("8"); g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), NULL); gtk_grid_attach(GTK_GRID(grid), button, 1, 1, 1, 1); button = gtk_button_new_with_label("9"); g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), NULL); gtk_grid_attach(GTK_GRID(grid), button, 2, 1, 1, 1); button = gtk_button_new_with_label("/"); g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), NULL); gtk_grid_attach(GTK_GRID(grid), button, 3, 1, 1, 1); gtk_widget_show_all(window); gtk_main(); return 0; } ``` 这段代码添加了一个文本框和四个按钮,当按钮被点击时会调用 `button_clicked` 函数。需要注意的是,我们使用了一个 GTK+ 的容器 `gtk_grid_new()`,它可以让我们灵活地布置窗口中的控件。 4. 实现计算器的功能 最后,我们需要在按钮点击事件中实现计算器的功能。下面是一个简单的计算器的代码: ```c #include <gtk/gtk.h> int main(int argc, char *argv[]) { GtkWidget *window; GtkWidget *grid; GtkWidget *button; GtkWidget *entry; int i, j; char buf[10]; gtk_init(&argc, &argv); window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_title(GTK_WINDOW(window), "Calculator"); gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER); gtk_window_set_default_size(GTK_WINDOW(window), 230, 250); gtk_container_set_border_width(GTK_CONTAINER(window), 10); grid = gtk_grid_new(); gtk_container_add(GTK_CONTAINER(window), grid); entry = gtk_entry_new(); gtk_entry_set_alignment(GTK_ENTRY(entry), 1); gtk_widget_set_size_request(entry, 200, 30); gtk_grid_attach(GTK_GRID(grid), entry, 0, 0, 4, 1); char *text[16] = {"7", "8", "9", "/", "4", "5", "6", "*", "1", "2", "3", "-", ".", "0", "=", "+"}; for (i = 0; i < 16; i++) { button = gtk_button_new_with_label(text[i]); gtk_widget_set_size_request(button, 45, 35); gtk_grid_attach(GTK_GRID(grid), button, i % 4, i / 4 + 1, 1, 1); g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), entry); } gtk_widget_show_all(window); gtk_main(); return 0; } void button_clicked(GtkWidget *button, gpointer data) { const gchar *text = gtk_button_get_label(GTK_BUTTON(button)); gchar *entry_text = gtk_entry_get_text(GTK_ENTRY(data)); gchar buf[50]; if (g_ascii_strcasecmp(text, "=") == 0) { double result = evaluate(entry_text); sprintf(buf, "%.2f", result); gtk_entry_set_text(GTK_ENTRY(data), buf); } else { strcat(entry_text, text); gtk_entry_set_text(GTK_ENTRY(data), entry_text); } } double evaluate(const gchar *expr) { GError *error = NULL; double result; if (gdk_threads_enter()) { if (gdk_threads_enter()) { if (gdk_threads_enter()) { if (gdk_threads_enter()) { if (gdk_threads_enter()) { if (!gdk_threads_enter()) { return 0.0; } } } } } } if (gdk_threads_leave()) { if (gdk_threads_leave()) { if (gdk_threads_leave()) { if (gdk_threads_leave()) { if (gdk_threads_leave()) { if (!gdk_threads_leave()) { return 0.0; } } } } } } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } if (!gdk_threads_enter()) { return 0.0; } if (!gdk_threads_leave()) { return 0.0; } gdouble result; gboolean success = g_strtod_with_fixed(expr, &result, &error, "en_US.utf8"); if (success) { return result; } else { g_error_free(error); return 0.0; } } ``` 这段代码添加了一个 `evaluate` 函数,用于计算表达式。在 `button_clicked` 函数中,我们通过 `gtk_entry_get_text` 函数获取文本框中的文本,然后通过 `evaluate` 函数计算结果,并把结果显示在文本框中。 需要注意的是,我们在 `evaluate` 函数中使用了 `gdk_threads_enter/leave` 函数来保证多线程安全,因为 GTK+ 是多线程的。这些函数的作用是进入/离开 GTK+ 的主线程。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值