c-如何将2个或多个GTK小部件传递给回调函数



我见过有人传递这样的小部件

static void on_button_click(GtkWidget *button, gpointer data) {
gtk_label_set_label(GTK_LABEL(data), "Hello, World!");
}
...
g_signal_connect(button, "clicked", G_CALLBACK(on_button_click), label);

但是如何传递两个小部件,比如标签和条目?

我想写一个计算器,所以当用户点击按钮时,我需要读取条目,解析并将结果写入标签。

提前感谢你帮助这个角落。

最后一个参数(gpointer数据(可以指向您想要的任何内容,因此选项基本上是无限的。

我认为从";演示应用程序的快速破解";高达";用于大型、复杂应用的可扩展/可维护";,其中一些选项可能是:

  1. 对于一个只有少数小部件的简单程序,我可能倾向于将GtkWidget指针存储在全局内存中:

    GtkWidget *window;
    GtkWidget *label;
    GtkWidget *btnEnter;
    GtkWidget *btnClear;
    GtkWidget *entry;
    // copy entry to label for simple demo purposes
    static void on_enter_button_click(GtkWidget *button, gpointer data) {
    // data unused, just get global references to label + entry
    gtk_label_set_label(GTK_LABEL(label), gtk_entry_get_text(entry));
    }
    // clear the label. maybe this is another function your calculator has
    static void on_clear_button_click(GtkWidget *button, gpointer data) {
    // data unused, just get global references...
    gtk_label_set_label(GTK_LABEL(label), "");
    }
    int main(int argc, char**argv){
    // Initialize all the widgets here
    // register unique callbacks
    g_signal_connect(btnEnter, "clicked", G_CALLBACK(on_enter_button_click), NULL);
    g_signal_connect(btnClear, "clicked", G_CALLBACK(on_clear_button_click), NULL);
    }
    
  2. 如果您不喜欢使用全局内存,或者想要稍微增强扩展/重构/重用代码的能力,您可以将它们分组到一个结构中:

    struct MyWidgets {
    GtkWidget *window;
    GtkWidget *label;
    GtkWidget *btnEnter;
    GtkWidget *btnClear;
    GtkWidget *entry;
    };
    // copy entry to label for simple demo purposes
    static void on_enter_button_click(GtkWidget *button, gpointer data) {
    struct MyWidgets *widgets = (struct MyWidgets*) data;
    gtk_label_set_label(GTK_LABEL(widgets->label), gtk_entry_get_text(widgets->entry));
    }
    // clear the label... maybe this is another function your calculator has?
    static void on_clear_button_click(GtkWidget *button, gpointer data) {
    struct MyWidgets *widgets = (struct MyWidgets*) data;
    // data unused, just get global references...
    gtk_label_set_label(GTK_LABEL(widgets->label), "");
    }
    int main(int argc, char**argv){
    struct MyWidgets widgets;
    // Initialize all the widgets here
    // register unique callbacks
    g_signal_connect(btnEnter, "clicked", G_CALLBACK(on_enter_button_click), &widgets);
    g_signal_connect(btnClear, "clicked", G_CALLBACK(on_clear_button_click), &widgets);
    }
    

但对于一些非常简单的事情,上面基本上和第一个例子相同,但有额外的步骤:(。

  1. 另一种替代方案可以是在任何GtkContainer"内对小部件进行分组;类";,在将对象分组到特定布局中,然后使用类似gtk_widget_get_parent()的东西来获取父容器,然后使用GtkContainer上允许迭代子容器的几种方法中的任何一种,这可能会自然地失败。

  2. 另一种选择是复合窗口小部件。本教程演示了其中的一些概念,并实现了用于处理多个小部件的单个回调函数:https://www.cc.gatech.edu/data_files/public/doc/gtk/tutorial/gtk_tut-20.html

最新更新