【问题标题】:How do I get a list of all windows on my gnome2 desktop using pygtk?如何使用 pygtk 获取 gnome2 桌面上所有窗口的列表?
【发布时间】:2012-02-19 20:52:32
【问题描述】:

我对一些 gtk 和 gnome 概念有些困惑。我试图在我的 gnome2 桌面上获取非最小化窗口的列表,但是在阅读了 pygtk 文档并检查了结果之后,我无法理解结果。

下面的两个 sn-ps 似乎都不起作用。

首先我尝试了这个..

>>> gtk.gdk.window_get_toplevels()
[<gtk.gdk.Window object at 0xb74339b4 (GdkWindow at 0x8a4c170)>]

>>> gtk.gdk.window_get_toplevels()[0].get_children()
[]

然后这个

>>> d = gtk.gdk.DisplayManager()   
>>> d.get_default_display().get_screen(0).get_root_window().get_children() 
[<gtk.gdk.Window object at 0x89dcc84 (GdkWindow at 0x8a4c170)>, <gtk.gdk.Window object at 0x89dccac (GdkWindow at 0x8a4c0c0)>] 

如控制台输出所示,第二个选项返回两个窗口。但我一直无法弄清楚它们是什么。他们都没有孩子,无论我的桌面上有多少个窗口,我总是得到这两个窗口。

谁能解释典型的基于 gtk 的桌面环境的对象层次结构? 我不明白为什么上面的代码不起作用。

请不要将资源的替代解决方案发布到 wnck、xlib、qt 等。我更感兴趣的是了解我做错了什么,而不是获得诸如检查其他库之类的建议。

【问题讨论】:

    标签: python gtk pygtk gnome window-management


    【解决方案1】:

    您的限制就像说“我想只用一根香蕉来制作 CD 播放器。请不要发布求助于激光的替代解决方案。” GTK 做不到,你使用了错误的工具来完成这项工作。

    这里解释了“窗口”的实际含义以及您的代码为何不起作用:

    首先,您需要了解gtk.Windowgtk.gdk.Window 之间的区别。 GTK 窗口是可以包含其他小部件的顶级 GTK 小部件。它通常链接到桌面上的一个窗口,但不一定是 - 在 GTK 3 中有一个 OffscreenWindow

    另一方面,GDK 窗口依赖于平台。在 X 桌面上,它是一个围绕 X 窗口的薄包装,它不一定是顶级桌面窗口。在其他系统上,它的存在是为了抽象掉窗口系统。 GDK 窗口接收事件,因此一些 GTK 非窗口小部件有自己的 GDK 窗口。 “窗口”对于这些对象来说确实是一个糟糕的名字,但它是从 X 继承而来的,它可能不会改变。

    每个 GTK 进程只知道其自己的窗口。您可以使用gtk.window_list_toplevels() 获取您自己的 应用程序的顶级 GTK 窗口列表。获取这些窗口的子窗口应该会返回它们包含的 GTK 小部件。但是,您不能进入其他进程窗口的小部件层次结构。例如,如果另一个进程有一个带有子窗口小部件的窗口,该窗口是您的进程不知道的自定义窗口小部件,该怎么办?它应该报告什么作为该小部件的类型?

    据我了解,使用gtk.gdk.window_get_toplevels() 获取顶级 GDK 窗口列表与获取顶级 X 窗口列表基本相同。您无法知道它们是什么类型的窗口 - 它们可能是 Gnome 面板,也可能是 Qt 窗口,或者它们可能是与桌面窗口不对应的其他东西。

    Libwnck(link 对其功能的概述)可以为您提供非最小化窗口及其标题的列表,但它不允许您查看其中的内容。没有办法做到这一点。 Libwnck 在内部使用 GDK,所以从技术上讲,您可以使用 GDK 来完成,但是如果已经有一个库可以为您做到这一点,您为什么还要打扰呢?如果你真的想自己做,请查看 libwnck 源代码。

    【讨论】:

    • 我并不是要粗鲁,但我认为您的回答并不令人满意。在您的回复结束时,您揭穿了您最初的香蕉 CD 阅读器类比。我知道 gtk 和 dtk.gdk 窗口之间的区别,如果你仔细阅读我的问题,你会注意到这有点离题......虽然我确实提到我很困惑,所以我想我声称过失。
    • 我猜底线是,为什么gtk.gdk.window_get_toplevels() 不输出您描述的结果?至于对窗口进行排序,我的印象是它们具有唯一目的的属性。
    • 好的,我想我将您的问题解释为为什么您无法获取 windows 的子 widgets。我不知道为什么 GDK 调用没有做你想要的。也许你应该看看 libwnck 源代码,看看它是如何工作的?
    【解决方案2】:

    您获得的窗口是在您的进程中创建的窗口。要获取窗口列表,需要查询根窗口的属性,如下所示:

    import gtk.gdk
    root = gtk.gdk.get_default_root_window()
    for id in root.property_get('_NET_CLIENT_LIST')[2]:
        w = gtk.gdk.window_foreign_new(id)
        if w:
            print(w.property_get('WM_NAME')[2])
    

    请注意,GDK 是底层操作系统图形引擎(X11/Quartz/Aqua/GDI 等)上的一个薄层,不同 NIX 设备上的结果可能会有所不同。

    【讨论】:

    • 回复的最后一句话非常不正确。 GDK不是“小部件引擎的瘦包装器”,它是用于实现 GTK 的绘图/窗口库。 Qt 和 Motif 与 GDK 没有任何联系。
    • @user4815162342 非常感谢,已修复。
    猜你喜欢
    • 2013-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 1970-01-01
    相关资源
    最近更新 更多