gtk中如何让另一个线程向GUI线程发送自定义消息?

fish_kun 2010-10-13 05:19:42
以前没做过gtk的程序,现在有这样一个需求。

linux下的一个gtk程序,它总共有两个线程,一个主线程,一个工作线程。(按照windows上的开发经验,我姑且这样描述)

工作线程一直在后台运行,它在处理完某些事情后需要告知用户(在GUI上显示相关结果)。

以前我在windows上是这样实现的,当工作线程需要告知用户一些信息时,就发送自定义消息给GUI线程,GUI线程相应的消息接收函数会根据接收到的消息来更新GUI界面。

我现在也想在gtk中实现类似于windows上面的这种设计,gtk上全是回调,本人对它的机制还不是太清楚,只是觉得它要么是select,要么就poll了一些设备文件(鼠标,键盘)来响应用户的输入,可对于这种另外一个线程发起的消息(也许应该叫事件,信号)的处理,我找来找去也没找到相应的方法,希望大家能指点一下。
...全文
207 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
hitlijinfeng 2010-12-10
  • 打赏
  • 举报
回复
[code=C/C++]/*-------------------------------------------------------------------------
* Filename: gtk-thread.c
* Version: 1.99.1
* Copyright: Copyright (C) 1999, Erik Mouw
* Author: Erik Mouw <J.A.K.Mouw@its.tudelft.nl>
* Description: GTK threads example.
* Created at: Sun Oct 17 21:27:09 1999
* Modified by: Owen Taylor <otaylor@gtk.org>
* Modified at: Wed May 28 10:43:00 2003
*-----------------------------------------------------------------------*/
/*
* Compile with:
*
* cc -o gtk-thread gtk-thread.c `pkg-config --cflags --libs gtk+-2.0 gthread-2.0`
*
* Thanks to Sebastian Wilhelmi for pointing out some bugs in earlier versions.
*
*/

#include <unistd.h>
#include <gtk/gtk.h>

#define YES_IT_IS (1)
#define NO_IT_IS_NOT (0)

typedef struct
{
GtkWidget *label;
int what;
} yes_or_no_args;

G_LOCK_DEFINE_STATIC (yes_or_no);
static volatile int yes_or_no = YES_IT_IS;

void destroy(GtkWidget *widget, gpointer data)
{
gtk_main_quit();
}

void *argument_thread(void *args)
{
yes_or_no_args *data = (yes_or_no_args *)args;
gboolean say_something;

for(;;)
{
/* sleep a while */
sleep(g_random_int_range (1, 4));

/* lock the yes_or_no_variable */
G_LOCK(yes_or_no);

/* do we have to say something? */
say_something = (yes_or_no != data->what);

if(say_something)
{
/* set the variable */
yes_or_no = data->what;
}

/* Unlock the yes_or_no variable */
G_UNLOCK(yes_or_no);

if(say_something)
{
/* get GTK thread lock */
gdk_threads_enter();

/* set label text */
if(data->what == YES_IT_IS)
gtk_label_set_text(GTK_LABEL(data->label), "O yes, it is!");
else
gtk_label_set_text(GTK_LABEL(data->label), "O no, it isn't!");

/* Make sure all X commands are sent to the X server; not strictly
* necessary here, but always a good idea when you do anything
* from a thread other than the one where the main loop is running.
*/
gdk_flush ();

/* release GTK thread lock */
gdk_threads_leave();
}
}

return NULL;
}

int main(int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *label;
GError *error = NULL;
yes_or_no_args yes_args, no_args;

/* init threads */
g_thread_init(NULL);
gdk_threads_init();

/* init gtk */
gtk_init(&argc, &argv);

/* create a window */
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

g_signal_connect(window, "destroy",
G_CALLBACK(destroy), NULL);

gtk_container_set_border_width(GTK_CONTAINER (window), 10);

/* create a label */
label = gtk_label_new("And now for something completely different ...");
gtk_container_add(GTK_CONTAINER(window), label);

/* show everything */
gtk_widget_show(label);
gtk_widget_show (window);

/* create the threads */
yes_args.label = label;
yes_args.what = YES_IT_IS;
if (!g_thread_create(argument_thread, &yes_args, FALSE, &error))
{
g_printerr ("Failed to create YES thread: %s\n", error->message);
return 1;
}

no_args.label = label;
no_args.what = NO_IT_IS_NOT;
if (!g_thread_create(argument_thread, &no_args, FALSE, &error))
{
g_printerr ("Failed to create NO thread: %s\n", error->message);
return 1;
}

/* enter the GTK main loop */
gdk_threads_enter();
gtk_main();
gdk_threads_leave();

return 0;
}
bourbaki 2010-11-05
  • 打赏
  • 举报
回复
用g_signal_emit
fish_kun 2010-11-05
  • 打赏
  • 举报
回复
To cr4315

能说的详细一点吗?
Applic 2010-11-05
  • 打赏
  • 举报
回复
g_signal_new给你的your_widget加一个your_signal
g_signal_connect (your_widget, "your_signal", G_CALLBACK (your_callback), &your_parameters);
线程里适时g_signal_emit_by_name ((gpointer) your_widget, "your_signal");
your_callback和创建线程时都可传递参数
justkk 2010-10-21
  • 打赏
  • 举报
回复
没做过gtk界面的路过..
fish_kun 2010-10-21
  • 打赏
  • 举报
回复
又加了10分,悬赏啊!!!
cr4315 2010-10-21
  • 打赏
  • 举报
回复
直接signal过去不行?
fish_kun 2010-10-14
  • 打赏
  • 举报
回复
期待大家能解答一下。

23,116

社区成员

发帖
与我相关
我的任务
社区描述
Linux/Unix社区 应用程序开发区
社区管理员
  • 应用程序开发区社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧