如何连接 wxWidgets、GTK2 小部件和 X11 windows?

How do I connect wxWidgets, GTK2 widgets, and X11 windows?

我从文档中的各种 wxWidgets class 引用中收集到(example) that the wxWidgets used to build a GUI basically inherit from wxWindow. I see from the comments in the source of wxWidgets/window.cpp 每个 wxWindow 都有一个指向存储在 m_widget 成员中的某个 GtkWidget 的指针wxWidget 对象的。从相同的源代码注释中,我还看到 m_wxwindowwxWindow class 的成员,并且可能包含指向 wxPizza 对象的指针例如 wxWindow 有一个客户区供绘图和儿童使用。

我正在开发需要此类功能的应用程序。我正在扩展一个 wxWidgets class 来创建我自己的小部件,它需要包含一个可绘制的 X11 window,我不太确定如何将它们全部连接起来,而且我很难找到一个使用文档的解决方案。

当我创建我的自定义小部件时(在 Create 方法中),我可以看到 m_widgetm_wxwindow 都是 NULL,所以从这个和我上面提到的,我收集这些是我应该创建以形成我的客户区的 GtkWidget 对象。首先,我试过这个:

m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);

哪种效果好但不太像我想要的。我能够从 GtkWidget 获得 XID 并且 X11 window 的行为符合预期。但这会在我的主要 wxWidgets 应用 window 之外创建一个新的 window。除了嵌入到我的主 wxWidgets 应用程序 window 之外,我想要的是这个确切的功能。我的自定义 class 已添加到 wxBoxSizer,如下所示:

sizer->Add(my_widget, 1, wxEXPAND | wxALL, 0);

其中 sizer 是 wxBoxSizermy_widget 是我的自定义小部件。

然后我尝试创建 m_widget 作为几种不同类型的 GtkWidget 但是这些都导致了 运行-time 在尝试使用 gtk_widget_realize 和尝试得到 XID.

// These don't work
m_widget = gtk_drawing_area_new();
m_widget = gtk_vbox_new(false, 0);

这些是我在尝试上述操作时收到的错误消息:

Gtk: IA__gtk_widget_realize: assertion 'GTK_WIDGET_ANCHORED (widget) || GTK_IS_INVISIBLE (widget)' failed
Gdk: gdkdrawable-x11.c:952 drawable is not a pixmap or window
Check failed: xwindow.

所以我这是一个多部分问题:

谢谢!

更新: 对不起,我忘了说,这是 GTK2 的。感谢@andlabs 指出这一点。

更新 2: @VZ。建议我澄清我要做什么。

我正在使用需要访问 X11 window 的库,但不会创建 window 本身。当我初始化库时,我需要向它传递一个 X11 window 句柄 (XID)。然后图书馆将绘制到 window。我想在我的 wxWidgets 应用程序中创建这个 window。我正在尝试扩展 wxWidgets class 以便我能够将这些 X11 windows 添加到基于我应用程序中 wxSizer 的小部件。

我知道 gtk_window_new() 不是我要找的,因为它创建了一个新的顶级 window,而我想要一个 window 嵌入到我的 wxWidgets 应用程序中。这只是我一路尝试的东西。

了解您到底想做什么真的很有帮助。您谈论 GtkWidgetss 但随后显示 gtk_window_new() 调用创建了一个新的(顶级)window,这是完全不同的东西,只能由 wx 处的 wxTopLevelWindow 表示等级.

您需要在 wxWidgets 应用程序中包装现有的 GtkWidget 吗?如果是这样,您应该只使用 wxNativeWindow。即使您不使用最新版本,您仍然可以轻松 reuse/duplicate 它的代码。

是否需要包装现有的 XWindow?那么它就更难了,因为你不能用 wxGTK 轻松地做到这一点。您可以使用 wxX11,但此端口状态不佳,因此它可能不是最好的主意,除非您的需求非常有限。最好的方法可能是先将 X window 包装在 GtkWidget 中,然后按上述方式进行。


更新后,您似乎只需要现有 window 的 XID。这比嵌入 GTK+ 小部件更简单,因为您可以使用 wxWindow::GetHandle() 获取 GtkWidget,然后使用 gtk_widget_get_window() 获取其 GdkWindow,最后使用 GDK_WINDOW_XID() 获取获取 XID。