创建gtk信号,用于编辑在其他线程中运行的GtkWidget

时间:2018-05-15 09:18:09

标签: c pthreads gtk signals

我有一个应用程序,它基本上以终端模式运行,但它可以在另一个线程中打开它的GUI部分(带有GtkTextView的简单窗口来打印一些消息)。 当主线程中发生某些事件时,我需要手动更新此GtkTextView的内容。为此,我创建了一个'new-message-received'信号,该信号应该传递一个指向char数组 msg 的指针,并带有要打印的消息

创建新信号:

g_signal_new("new-message-received",
              G_TYPE_OBJECT, G_SIGNAL_RUN_FIRST,
              0, NULL, NULL,
              g_cclosure_marshal_VOID__POINTER,
              G_TYPE_NONE, 1, G_TYPE_POINTER);

将其与处理程序功能连接:

g_signal_connect(G_OBJECT(demo_window), "new-message-received", 
                 G_CALLBACK(print_demo_message),(gpointer)msg);

并发出信号:

if (flag){
memset(msg, 0, 256);
g_signal_emit_by_name(G_OBJECT(demo_window), 
                     "new-message-received", 
                     (gpointer) msg);
...
}

问题是信号处理程序得到一些破坏的指针(我尝试将其打印到stdout - 它总是一些随机的4个符号)而不是传递消息。 处理程序是:

void print_demo_message(gpointer *param)
{
    const gchar* message = (const gchar*)param;
    g_print("Got message: %s\n", message);
    ...
}

输出如下:

Got message: p���

我尝试了什么:

  1. 使msg成为全局变量以避免重新初始化 - 不 结果
  2. 在信号创建中使用通用编组器 - 无结果
  3. 将链接传递给msg地址而不是指向它的指针,不 结果也是。
  4. 问题是 - 我做错了什么?

    提前致谢。

1 个答案:

答案 0 :(得分:1)

不得不自己解决这个问题,根本不需要使用信号。

GTK的主线程是一个线程,其中调用gtk_main()。禁止访问其外部任何GTK对象的主线程。因此,为了启动GTK GUI的线程,我使用了g_thread_new()g_idle_add(print_demo_message, msg)来"请问" GTK主线程将msg粘贴到GtkTextView

所以,现在它看起来像这样:

APP MAIN THREAD:

if(%some_condition%){
     msg = malloc(256);
     sprintf(msg, "Some text");
     g_idle_add(print_demo_message, msg);
}
GUI THREAD:

boolean print_demo_message(gpointer data)
{
    gchar* message = data;
    g_print("Got message: %s\n", message);
 ...
}

消息转移好,就像魅力一样:)