- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
这是我在这里的第一篇文章,我创建这个帐户是因为我有点难过。我正在尝试练习将结构作为参数传递给回调,为此我在窗口中创建了一个带有按钮的简单程序。在第一次迭代中,按下标签为“Button 1”的按钮会将其更改为标签为“Button 2”的不同按钮,而在第二次迭代中,通过将鼠标悬停在按钮上来完成更改。下面是第一次迭代的代码
#include <gtk/gtk.h>
typedef struct {
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *window;
} example;
void callback_func (GtkWidget *ignored, example *test) {
GtkWidget *window=test->window;
GtkWidget *changebutton1=test->button1;
GtkWidget *changebutton2=test->button2;
gtk_container_remove(GTK_CONTAINER(window),changebutton1);
gtk_container_add(GTK_CONTAINER(window),changebutton2);
gtk_widget_show_all(window);
}
void callback_func2 (GtkWidget *ignored, example *test) {
GtkWidget *window=test->window;
GtkWidget *changebutton1=test->button1;
GtkWidget *changebutton2=test->button2;
gtk_container_remove(GTK_CONTAINER(window),changebutton2);
gtk_container_add(GTK_CONTAINER(window),changebutton1);
gtk_widget_show_all(window);
}
int main(int argc, char *argv[]) {
example test;
gtk_init(&argc,&argv);
GtkWidget *window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget *changebutton1=gtk_button_new_with_label("Button 1");
GtkWidget *changebutton2=gtk_button_new_with_label("Button 2");
test.window=window;
test.button1=changebutton1;
test.button2=changebutton2;
g_signal_connect (G_OBJECT (window), "delete_event", G_CALLBACK (gtk_main_quit), NULL);
g_signal_connect (G_OBJECT (window), "destroy", G_CALLBACK (gtk_main_quit), NULL);
gtk_container_add(GTK_CONTAINER(window),changebutton1);
g_signal_connect (G_OBJECT (changebutton1), "clicked", G_CALLBACK (callback_func), (gpointer*)&test);
g_signal_connect (G_OBJECT (changebutton2),"clicked",G_CALLBACK(callback_func2),(gpointer*)&test);
gtk_widget_show_all(window);
gtk_main ();
return 0;
}
当运行上面的代码时,通过单击按钮一次,按钮会正确切换,但是当我再次单击它时(现在调用 callback_func2 而不是 callback_func,除了按钮切换位置外它们基本上是相同的)我得到这个:(gtktesting.exe:92024): Gtk-CRITICAL **: gtk_container_add: 断言 `GTK_IS_WIDGET (widget)' 失败
如果我用“enter_notify_event”和“leave_notify_event”替换“clicked”事件,第一个更改也会失败,现在会产生更多错误。
有人知道这是怎么回事吗?
另外,一个额外的问题。我几乎从另一篇文章中复制并粘贴了这段代码的基础,因为我一直试图自己编写它但没有成功,所以我想测试它是否有效。我注意到回调中的第二个参数是“example *test”。谁能解释“示例”类型?这只是结构的名称,我不知道它在那里做什么。
最佳答案
tl;dr
尝试:
test.window = g_object_ref(window);
test.button1 = g_object_ref(changebutton1);
test.button2 = g_object_ref(changebutton2);
完整解释
GTK+ 中的对象(即 GObject
的子类)是引用计数的。这意味着,每个对象(例如 Widget)都有“引用计数”——指向它的指针的数量。当数字达到 0 - 对象被释放。创建的对象的引用计数为 1。由于 C 没有智能指针,C++ 也没有类似的东西,因此必须手动完成引用计数。用户必须调用 g_object_ref
才能保留引用(我交替使用“指针”和“引用”这两个词),并在用户完成引用后调用 g_object_unref
。这确保没有对象在使用时被破坏。
GtkWidget
很特别,因为它以“ float ”引用开始生命。这意味着第一次引用小部件时,它的引用计数不会增加——它的“ float ”引用是“沉没”的。之后它的行为就像任何其他 GObject
一样。
当您创建按钮时,它们的引用计数为 1(“ float ”)。当它们被添加到它们的容器中时,它们的引用仍然是 1(但“沉没”)。这意味着,按钮由它们添加到的容器拥有。
现在,当您从容器中移除按钮时:
gtk_container_remove(GTK_CONTAINER(window),changebutton1);
changebutton1
的引用计数减少,降至 0,这会强制对象销毁,并且 test.button1
现在是悬挂指针。
为了克服这个问题,只要您想要存储指向 GObject
的指针,请使用 g_object_ref
。这样您就可以表达“test
参与了 changebutton1
的所有权”(或者,“test
有兴趣保留 changebutton1
活着)。
完成 window
、button1
和 button2
后,对它们调用 g_object_unref
。
奖金问题
Also, a bonus question. I pretty much copied and pasted the base of this code from another post, since I had been trying to write it by myself unsuccessfully and I wanted to test if it works at all. I noticed that the second argument in the callbacks is "example *test". Can anybody explain the "example" type? It's only the name of the stucture, and I've no idea what it's doing there.
示例
定义如下:
typedef struct {
GtkWidget *button1;
GtkWidget *button2;
GtkWidget *window;
} example; // declares type "example"
GObject
信号系统的设计方式允许将任意指针作为最后一个参数传递给回调,因此程序员可以从创建信号连接的地方传递额外信息( g_signal_connect
), 一个回调。
关于c - GTK2+ 错误 : GTK_IS_CONTAINER & GTK_IS_WIDGET failed,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31276404/
我正在尝试使用 GTK 构建一个 hello world,其中包括以下行: #include 如你所料。 提供的 Makefile 包含以下行: GTK_INCLUDE = -I/usr/local
我对 GTK 术语感到困惑。根据Wikipedia ,似乎有与 GTK+ 的绑定(bind),称为 GTK (GtkAda) 和 GTK2 (gtk2hs、Gtk2-Perl)。 有人可以帮我解决这个
我在 Gtk.Fixed 中有一个 Gtk.TextView,我设置了它的宽度和高度以及换行模式。 我的问题是,当用户插入的文本多于设置大小时,我需要避免 TextView 扩展。在那种情况下,我只需
我考虑使用带有 Broadway 后端的 GTK+ 来开发设备控制应用程序。 设备的功能类似于宽带调制解调器/路由器(我特意选择了所有人都熟悉的示例 :-))。 设备应通过网络浏览器远程控制。 我担心
我想更改 Windows 的默认 GTK 主题。我知道该怎么做:通过修改 settings.ini 文件,或者像这样: settings = gtk_settings_get_default(); g
在 GTK+ 3 中将多个键盘快捷键绑定(bind)到一个操作的最佳方法是什么? 这几天我一直在寻找这个问题的答案,但一无所获。函数 gtk_accelerator_parse 不支持逗号分隔的快捷方
虽然 Gtk.table 已被弃用,但我用它获得了更好的结果,而不是推荐的 Gtk.Grid。 这可能是我的错误,但我找不到问题。 我的目标是创建一个 Gtk 窗口,顶部有一个笔记本,下面有两个按钮。
虽然 Gtk.table 已被弃用,但我用它获得了更好的结果,而不是推荐的 Gtk.Grid。 这可能是我的错误,但我找不到问题。 我的目标是创建一个 Gtk 窗口,顶部有一个笔记本,下面有两个按钮。
是否可以在辅助线程而不是主线程中运行 GTK 的主循环? 最佳答案 是的,您可以在任何线程中使用主循环,但您只能从创建它的线程访问它。 但是,这不是一件常见的事情,并且可能有更好的方法来做您想做的任何
我从一个空表开始(只有一列的列表存储) 我希望用户能够导入 CSV 文件并显示内容。导入文件有效,确实显示了 CSV 数据,但保留了原始列(标题为“无数据”)。我该如何摆脱它? 我已经尝试删除 Tre
我正在尝试找出是否可以使用适用于 Windows 的 Python 3.2.2 或更高版本编写基于 Python 的 Windows 桌面小部件。上述项目完全令人困惑。他们中的任何一个支持我正在寻找的
我正在构建一个使用 kivy 的 cefpython 小部件的 Kivy 应用程序。 在执行我的程序时,每当我将文本输入小部件添加到 View 中时,我的应用程序都会崩溃并出现以下错误: Gtk-ER
Vala 中的源代码: using GLib; using Gtk; class MainWindow : Window { public static int main (string[] a
为什么 set_size_request(800,600) 在 DrawingArea 小部件上调用(也用 Gtk.Button 测试)导致大小为 958 x 791 px 的窗口,而在 Window
当我手动构建项目时,它会正确构建: gcc main.c -o midget `pkg-config --cflags --libs gtk+-3.0` 当我尝试使用 Makefile 时,它失败
如果有人对 the following function 有任何经验,我很感兴趣gtk.Window/gtk.Widget 的 shape_combine_mask(shape_mask, offs
如果我正在编写一个想要通过使用颜色来传达一些信息的应用程序,我该如何更改给定小部件的背景色和前景色?如果可能的话,我想知道如何在空地中做到这一点,以及以编程方式(计算颜色)。 我也想知道如何对复杂的小
假设有问题的小部件是一个包含一个标签和两个按钮的 VBox。 此外,假设所需的旋转角度为 90°。 如何旋转它?我认为默认情况下这是不可能的,但我认为这是可能的。 但是,我不知道如何开始。我要编写自定
我想知道当 Gtk.Window 完全显示时发出哪个信号,完全显示是指显示窗口本身及其小部件。 我尝试了几个信号: 展示 意识到 可见性通知事件 设置焦点 但它们都无法正常工作。 我在网上找到的唯一有
GTK+ Button 小部件具有控制焦点获取的 focus_on_click 属性。但是我使用的 MenuToolButton 没有这样的属性。我不想关注点击。 如何摆脱它?谢谢! 最佳答案 如果您
我是一名优秀的程序员,十分优秀!