c - Lxpanel 插件和线程

标签 c multithreading gtk

我正在编写一个多线程 Lxpanel 插件(使用 C 和 GTK2),并且我试图在单独的线程中更改 GUI(例如,添加和删除小部件),但它不起作用 - 当我尝试时要添加标签,有一个空白区域。

//includes

typedef struct {
    GtkWidget *l1;
    GtkWidget *l2;
} Plug;

/*thread function*/
gboolean test_func(Plugin *plugin){
    Plug *priv=plugin->priv;
    gtk_container_remove(GTK_CONTAINER(plugin->pwid), priv->l1);
    gtk_container_add(GTK_CONTAINER(plugin->pwid), priv->l2);
    return FALSE;
}
/*called when plugin is added*/
static int test_constructor(Plugin *plugin, char **fp){
    Plug *priv=g_new0(Plug, 1);
    plugin->pwid=gtk_event_box_new();
    plugin->priv=priv;
    priv->l1=gtk_label_new("l1");
    priv->l2=gtk_label_new("l2");
    g_thread_new(
        "test_thread", (GThreadFunc)test_func, plugin
    );
    //g_idle_add((GSourceFunc)test_func, plugin);
    //test_func(plugin);
    gtk_container_add(GTK_CONTAINER(plugin->pwid), priv->l1);
    gtk_widget_set_size_request(plugin->pwid, 30, 25);
    gtk_widget_set_has_window(plugin->pwid, FALSE);
    gtk_widget_show_all(plugin->pwid);
    return 1;
}
/*called when plugin is removed*/
static void test_destructor(Plugin *plugin){
    Plug *priv=plugin->priv;
    gtk_widget_destroy(priv->l1);
    gtk_widget_destroy(priv->l2);
    g_free(priv);
}
/*settings*/
PluginClass test_plugin_class = {

    PLUGINCLASS_VERSIONING,

    type : "test",
    name : N_("test"),
    version: "1.0",
    description : N_("test"),

    one_per_system : TRUE,

    expand_available : FALSE,

    constructor : test_constructor,
    destructor  : test_destructor,
    config : NULL,
    save : NULL
};

我也尝试过 g_idle_add - 它也不起作用。当我在 test_func 函数中添加 gdk_threads_enter() 和 gdk_threads__leave() 时,lxpanel 就会挂起。我做错了什么?

非常感谢您的帮助。

最佳答案

在 GTK+ 中使用多线程通常是一个设计错误,并且通常很难纠正:我建议您尝试修改代码以适应事件循环驱动模型(例如使用 g_idle_add)。

至于为什么小部件不可见:您在将 l2 添加到容器之前调用 gtk_widget_show_all() 。这意味着您需要在某个时刻显式地将 l2 设置为可见(您可以在将其添加到容器之前执行此操作,例如在创建时)。

关于c - Lxpanel 插件和线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18052229/

相关文章:

c - 我的程序在代码的一部分中自行停止。如何修复它?

c - Linux | C 中的 Shell 实现 |输入重定向不显示

c++ - 如何在任何事件发生之前唤醒 epoll_wait()?

c++ - 编译器怎么知道不从锁定/解锁内部优化语句?在 C++ 中使用 boost::spinlocks

用 if 检查 char

objective-c - 为什么不能在每行声明多个方法原型(prototype)?

python - 如何处理 C 和 Python 之间的 IPC?

java - ATM如何在并发环境下工作

python - 将变量传递给对话框

c - 错误: unknown type name ‘WebKitWebFrame’