Gdkmm:如何破坏GDK窗口
gdkmm: how to destroy gdk window?
现状:我有一个带有事件窗口的自定义小部件(MyWidget)。问题:如果我创建,显示,然后,稍后,隐藏和销毁小部件,我从应用程序得到以下消息:
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);
}
事实证明,破坏您使用Gdk::Window::create()
创建的GDK窗口的正确方法是…你猜怎么着?在您的自定义小部件的on_unrealize()
方法中调用Gtk::Widget::unrealize()
,因为除了其他事情之外,这个基本方法为小部件的GDK窗口调用gdk_window_destroy()
。对于你的小部件有是"窗口"(即你应该调用set_has_window(true);
在构造函数和set_window(<your allocated GDK window>);
在on_realize()
回调。很明显的方法,不是吗?
我也应该说一些关于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);
}
- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 问:如何使用C++中的按钮从窗口打开窗口
- SDL 窗口不会弹出
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 如何在cpp文件之间切换窗口?在Qt中
- QuadTree只在窗口的右上角绘制
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 处理闪烁窗口事件
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- C++win32 API创建多个类似视口的窗口
- SFML RenderWindow打开窗口需要很长时间
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 获取 SFML 窗口的 HWND 和高可用性?
- 如何获取 GLFW 窗口 ID?
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- 用于窗口的 HID 终端
- SFML 文本未绘制在窗口上
- 如何为窗口截屏
- Gdkmm:如何破坏GDK窗口