gpt4 book ai didi

c - 如何确定 GTK 小部件是否已被销毁

转载 作者:太空狗 更新时间:2023-10-29 14:50:59 30 4
gpt4 key购买 nike

我有一些用 C 编写的 Gtk+ 代码,使用 Cairo 和一个计时器来制作一些动画。大多数情况下,当我单击关闭应用程序图标时,我会在终端上收到以下消息:

Gtk-CRITICAL **: gtk_widget_queue_draw: assertion `GTK_IS_WIDGET (widget)' failed

现在我假设这是幸福的,因为在我关闭应用程序的那一刻,计时器被触发并且主窗口小部件被访问但是已经被销毁了。确定一个 Gtk 小部件是否仍然有效并且可以被引用的常用方法是什么?

违规代码在这里:

gboolean rotate_cb( void *degrees )
{
rotation += DegreesToRadians((*(int*)(degrees)));
// Tell our window that it should repaint itself (ie. emit an expose event)
/* need to only call gtk_widget_queue_draw() if window is still valid / exists */
gtk_widget_queue_draw(window);
return( TRUE );
}

我假设一定有某种方法可以测试 window 是否仍然有效?

最佳答案

你的问题很微妙。这通常是由于 GObject/GtkObject 的所有权和销毁规则而发生的。让我提醒他们:

  • GObject 只是计数引用。当计数达到 0 时,它们将被销毁。新创建的对象的计数为 1。
  • GIinitallyUnowned 也是计数引用,当计数达到 0 时它们也会被销毁。但是新创建的对象有一个 float 计数。这意味着第一次递增计数时,它实际上并未递增,但 float 计数沉没,即转换为普通引用。

GtkObject GIinitiallyUnowned 对象,因此它们具有神奇的 float 计数

但你可能知道这一切......现在,我的问题:

Who owns the counter of the visible main GtkWindow?

这其实很简单,GTK 框架有一个列表,并保留每个可见 GtkWindow 的引用。但是,另一个问题:

When does the GTK framework free the references of its GtkWindow?

您还记得gtk_widget_destroy() 函数和destroy 信号吗?它们正是为此而生的:当你想删除一个顶层 GtkWindow 时,你调用 gtk_widget_destroy(),它会激活接收到的信号 destroy由 GTK 框架删除实际窗口并释放其对对象的引用。

问题的原因来了:如果 GTK 框架保留了对 GtkWindow 的唯一现有引用,则该对象实际上已被释放。如果那时,您的计时器尝试访问它,它将失败,因为窗口不再存在。

最后,(希望)解决方案出现了:

  • 启动计时器时,在窗口上调用 g_object_ref()/g_object_ref_sink()。还向窗口的 destroy 信号注册一个处理程序。
  • 在窗口的destroy信号的处理程序中:调用窗口的g_object_unref()并停止定时器。

当然,这个部分解决方案也应该有效,因为如果不发送 destroy 信号,窗口将不会被销毁:

  • 向窗口的destroy 信号注册一个处理程序。
  • 在窗口的destroy 信号的处理程序中:停​​止计时器。

但是,当您实际保留指向对象的指针时,增加对象的引用计数器被认为是一种很好的做法。

关于c - 如何确定 GTK 小部件是否已被销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11037988/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com