2013-04-14 54 views
0

现状: 我有一个事件窗口的自定义小部件(MyWidget)。
问题:如果我创建,显示和再后来,隐藏和销毁小部件我从应用程序的以下信息:gdkmm:如何销毁gdk窗口?

Gdk-WARNING **: losing last reference to undestroyed window

我已经找到了:我已经看过gdkwindow.c文件,并在GDK_WINDOW_DESTROYED(window) == FALSE时报告此消息。所以我不明白的是我应该如何正确摧毁我的窗口,以便最终调用函数gdk_window_destroy()。我认为最好的地方叫做Gdk::~Window()析构函数。但它是空的。而且文件中根本不存在gdk_window_destroy()文件。

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); 
} 

回答

0

它原来,破坏您与Gdk::Window::create()创建GDK窗口correctest方式是...你猜怎么着?请在on_unrealize()中调用Gtk::Widget::unrealize()方法,因为除此之外,此基本方法将为窗口小部件的GDK窗口调用gdk_window_destroy()。并为您的小部件是“windowful”(即你应该调用构造函数set_has_window(true);set_window(<your allocated GDK window>);on_realize()回调。很明显的方法,是不是?

我还要谈谈Gtk::Widget::realize()。不像Gtk::Widget::unrealize()你应该叫Gtk::Widget::realize()只有如果你的widget 没有一个GDK窗口(该方法假设作为断言)。

不幸的是,我没有时间和希望得到的最底部它并努力去理解为什么它是d一个是这样的,这个方法有什么原因和后果。否则我会提供更详细的解释。

您可以从GTK的自定义小部件教程中找到官方示例 here

而且我的窗口小部件的代码现在看起来像这样:

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); 
}