2013-04-14 43 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); 
}