我有一个应用程序,它基本上以终端模式运行,但它可以在另一个线程中打开它的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���
我尝试了什么:
msg
成为全局变量以避免重新初始化 - 不
结果msg
地址而不是指向它的指针,不
结果也是。问题是 - 我做错了什么?
提前致谢。
答案 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);
...
}
消息转移好,就像魅力一样:)