2013-04-14 5 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() 소멸자라고 생각했다. 그러나 그것은 비어 있습니다. 그리고 gdkwindow.cc 파일에는 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 방법이 밝혀졌다이야? 이 기본 메소드는 위젯의 GDK 윈도우에 대해 gdk_window_destroy()을 호출하기 때문에 사용자 정의 위젯의 메소드 인 on_unrealize()에서 Gtk::Widget::unrealize()을 호출 할 수 있습니다. 위젯 (즉 당신이 on_realize() 콜백. 아주 명백한 접근 방식에 생성자에서 set_has_window(true);set_window(<your allocated GDK window>);를 호출해야 "windowful"로을 가지고, 그것은하지 않습니다에 대한? 나는 또한 뭔가 말을해야

에 대한 Gtk::Widget::realize(). 달리 위젯 받을 GDK 창을 가지고 있지 않은 경우 Gtk::Widget::unrealize() 당신이 호출해야 Gtk::Widget::realize()에만.

불행하게도, 난 시간이과의 맨 아래에 도착하고자하지 않았다 (방법은 주장으로 가정합니다) 왜 그것이 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); 
}