我见过有人传递这样的小部件
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数据(可以指向您想要的任何内容,因此选项基本上是无限的。
我认为从";演示应用程序的快速破解";高达";用于大型、复杂应用的可扩展/可维护";,其中一些选项可能是:
-
对于一个只有少数小部件的简单程序,我可能倾向于将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); }
-
如果您不喜欢使用全局内存,或者想要稍微增强扩展/重构/重用代码的能力,您可以将它们分组到一个结构中:
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); }
但对于一些非常简单的事情,上面基本上和第一个例子相同,但有额外的步骤:(。
-
另一种替代方案可以是在任何
GtkContainer
"内对小部件进行分组;类";,在将对象分组到特定布局中,然后使用类似gtk_widget_get_parent()
的东西来获取父容器,然后使用GtkContainer
上允许迭代子容器的几种方法中的任何一种,这可能会自然地失败。 -
另一种选择是复合窗口小部件。本教程演示了其中的一些概念,并实现了用于处理多个小部件的单个回调函数:https://www.cc.gatech.edu/data_files/public/doc/gtk/tutorial/gtk_tut-20.html