如何在GUI中嵌入外部窗口(Python + Glade + Gtk3)

13

我开始使用Glade、Python和Gtk3库构建GUI。我想尝试在我的GUI中链接一个外部窗口,并将它放在一个容器内显示。这是否可能?哪种容器对象是最好的选择?

我开始搜索,但在Gtk2中易于使用的方法(例如此处)现在无法在Gtk3中使用。

我发现了一个非常有趣的帖子(此处),它允许我设置目标窗口的正确ID,但我仍然不知道如何在我的GUI中显示它。

我试图更改这些教程来使用cairo,但没有成功。

到目前为止,我的代码片段如下(我想在map_area容器中显示ID = 0x360000b的窗口,并且我必须使用“self.”处理结构)。暂时,map_area容器是一个Drawingarea。

# if condition occurs    
    Gdk.Window.process_all_updates()
    win_id = 0x360000b # from xwininfo command
    root_win = GdkX11.X11Display.get_default()
    win = GdkX11.X11Window.foreign_new_for_display(root_win, win_id)
    width = win.get_width()
    height = win.get_height()   
    self.map_area = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)               
    pixbuf = Gdk.pixbuf_get_from_window(win, 0, 0, width, height)
    cr = cairo.Context(self.map_area)   
    Gdk.cairo_set_source_pixbuf(cr, pixbuf, 0, 0)
    cr.paint()

有人能帮我吗? 非常感谢!


请查看 https://developer.gnome.org/gtk3/stable/GtkSocket.html - 这个解决方案需要其他进程的一些合作。 - Phillip
1
当然,这就是文档中所说的“其他”进程。但是外部进程需要与您的进程合作;也就是说,它必须积极地将其顶级窗口重新父化到由GtkSocket创建的窗口。例如,xterm具有-into选项可用于此操作。(如果您愿意将Xlib添加为脚本的依赖项,则可以为其他应用程序执行此操作。我将发布一个带有示例的答案。) - Phillip
事实证明,重新父化并不容易。有XReparentWindow函数可用,并且您还可以通过窗口的“reparent”函数从GdkX11访问该函数,但是如果尝试重新父化一个已经可见的窗口,至少xterm将退出。所以很抱歉我没有例子可以提供。 - Phillip
我之前尝试过这个,但最终走了一条稍微不同的路,因为我也遇到了类似的问题。我最后只需要应用程序的截图,所以我写了一个根据窗口标题来抓取窗口截图的工具,适用于Mac和Linux。它还使用了X11和Quartz来完成所有繁重的工作,所以速度相当快。仓库位于这里:https://github.com/Kush131/PyFastCap/。虽然代码看起来有点丑陋和hacky,但也许对你有所帮助! - Kush
@Phillip非常感谢您的尝试并确认这不是因为我懒惰而提出的问题:) 我希望在赏金奖励中能够“吸引”其他答案! - marcoresk
显示剩余3条评论
1个回答

1

感谢您的回答。与此同时,我已经停止了项目的这一部分,并在考虑后从GTK和Glade转移到了Qt-creator,但我肯定会去看看! - marcoresk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接