现状:我有一个带有事件窗口的自定义小部件(MyWidget)。
问题:--如果我创建、显示、然后隐藏并销毁小部件,我将从应用程序中得到以下消息:
Gdk-WARNING **: losing last reference to undestroyed window
我发现了什么:,我在gdkwindow.c文件中查看过,这条消息是在GDK_WINDOW_DESTROYED(window) == FALSE时报告的。所以,我不明白的是,我应该如何正确地销毁我的窗口,以便最终调用gdk_window_destroy()函数。我认为最好的地方叫它Gdk::~Window()破坏者。但它是空的。而且,gdk_window_destroy()在gdkwindow.cc文件中根本不存在。
on_realize()和on_unrealize()的回调在下面。
class MyWidget : public Gtk::Widget
{
...
private:
Glib::RefPtr<Gdk::Window> _event_window;
...
};
void Gtk::MyWidget::on_realize()
{
GdkWindowAttr attributes;
const Allocation & allocation = get_allocation();
attributes.event_mask = GDK_BUTTON_PRESS_MASK;
attributes.x = allocation.get_x();
attributes.y = allocation.get_y();
attributes.width = allocation.get_width();
attributes.height = allocation.get_height();
attributes.wclass = GDK_INPUT_ONLY;
attributes.window_type = GDK_WINDOW_CHILD;
_event_window = Gdk::Window::create(get_parent_window(), &attributes, GDK_WA_X | GDK_WA_Y);
_event_window->set_user_data(Widget::gobj());
set_window(get_parent_window());
set_realized();
}
void Gtk::MyWidget::on_unrealize()
{
_event_window->set_user_data(NULL);
_event_window.reset();
set_realized(false);
}发布于 2013-05-06 06:46:06
事实证明,破坏您用Gdk::Window::create()创建的GDK窗口的最正确方法是..你猜怎么着?要在定制小部件的Gtk::Widget::unrealize()方法中调用on_unrealize(),因为除了其他事情之外,这个基本方法还为小部件的GDK窗口调用gdk_window_destroy()。为此,您的小部件具有“窗口式”(即在构造函数中调用set_has_window(true);,在on_realize()回调中调用set_window(<your allocated GDK window>); )。很明显的方法,不是吗?
我也应该说一些关于Gtk::Widget::realize()的事情。与Gtk::Widget::unrealize()不同,只有当您的小部件没有GDK窗口时才应该调用Gtk::Widget::realize() (该方法假设这是一个断言)。
不幸的是,我没有时间,我希望了解它的最底层,并使之理解为什么要这么做,以及这种方法有什么原因和后果。否则,我会提供更详细的解释。
您可以从GTK关于自定义小部件这里的教程中找到一个正式的示例。
另外,我的小部件的代码现在看起来如下所示:
class MyWidget : public Gtk::Widget
{
...
private:
Glib::RefPtr<Gdk::Window> _event_window;
...
};
void Gtk::MyWidget::on_realize()
{
GdkWindowAttr attributes;
const Allocation & allocation = get_allocation();
attributes.event_mask = GDK_BUTTON_PRESS_MASK | GDK_EXPOSURE;
attributes.x = allocation.get_x();
attributes.y = allocation.get_y();
attributes.width = allocation.get_width();
attributes.height = allocation.get_height();
attributes.wclass = GDK_INPUT_OUTPUT;
attributes.window_type = GDK_WINDOW_CHILD;
_event_window = Gdk::Window::create(get_parent_window(), &attributes, GDK_WA_X | GDK_WA_Y);
_event_window->set_user_data(Widget::gobj());
set_window(_event_window);
set_realized();
}
void Gtk::MyWidget::on_unrealize()
{
_event_window->set_user_data(NULL);
_event_window.reset();
Widget::unrealize();
// it will call gdk_destroy_window() and
// set_realized(false);
}https://stackoverflow.com/questions/15999021
复制相似问题