如何在Ubuntu中使用PyGTK或GTK获取已打开窗口的列表?

11

如何在PyGTK,GTK或其他编程语言中获得已打开窗口的列表?在Ubuntu上?

编辑:

我想获取桌面上已打开目录的路径列表!


请澄清一下:您是否想要获取所有Nautilus窗口的所有选项卡中显示的目录列表? - akaihola
6个回答

13

欢迎来到2013年!这里提供的代码使用Wnck和其现代GObject Introspection库,而不是现在已经废弃的PyGTK方法。您还可以查看关于wnck的我的另一个答案

from gi.repository import Gtk, Wnck

Gtk.init([])  # necessary only if not using a Gtk.main() loop
screen = Wnck.Screen.get_default()
screen.force_update()  # recommended per Wnck documentation

# loop all windows
for window in screen.get_windows():
    print window.get_name()
    # ... do whatever you want with this window

# clean up Wnck (saves resources, check documentation)
window = None
screen = None
Wnck.shutdown()

关于文档,请查看Libwnck参考手册。它不是特定于Python的,但使用GObject Introspection的整个重点是通过gir绑定在所有语言中具有相同的API。

此外,Ubuntu默认安装了wnck和其对应的gir绑定,但如果需要安装它们:

sudo apt-get install libwnck-3-* gir1.2-wnck-3.0

这也将安装libwnck-3-dev,虽然不是必需的,但会安装有用的文档,您可以使用DevHelp进行阅读。


1
这个解决方案对我很有效,而被采纳的答案则会出现错误,指出没有 wnck.screen_get_default()。虽然这个答案比另一个答案更新,但我认为这应该是被采纳的答案,因为旧的那个不再起作用了。 - Zelphir Kaltstahl

10

你可能需要使用 libwnck 库:

http://library.gnome.org/devel/libwnck/stable/

我相信在 python-gnome 或一些类似的包中有 Python 的绑定。

一旦 GTK+ 主循环运行,你可以执行以下操作:

import wnck
window_list = wnck.screen_get_default().get_windows()

从该列表中的窗口中有一些有趣的方法是 get_name() 和 activate()。

当你点击按钮时,这将会把窗口的名称打印到控制台。但由于某种原因,我必须点击两次按钮。这是我第一次使用 libwnck 所以我可能遗漏了什么。 :-)

import pygtk
pygtk.require('2.0')
import gtk, wnck
class WindowLister: def on_btn_click(self, widget, data=None): window_list = wnck.screen_get_default().get_windows() if len(window_list) == 0: print "没有找到窗口" for win in window_list: print win.get_name()
def __init__(self): self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
self.button = gtk.Button("列出窗口") self.button.connect("clicked", self.on_btn_click, None)
self.window.add(self.button) self.window.show_all()
def main(self): gtk.main()
if __name__ == "__main__": lister = WindowLister() lister.main()

1
wnck.screen_get_default().get_windows() - 返回空列表 :( - john
在我的快速测试中,我必须先打开一个gtk+窗口(在我的Python进程中),然后调用才能正常工作。 - Sandy
2
如果您的应用程序是非 GUI 的,您可以在执行 "wnck.get_screen_default()" 之后加上 "while gtk.events_pending(): gtk.main_iteration()" 来刷新事件,以便获取窗口列表。 - akaihola
1
还有screen.force_update()。请参阅http://developer.gnome.org/libwnck/stable/getting-started.html中的常见陷阱。 - Bruce van der Kooij

4

无论出于何种原因,我无法发布评论,但我想将此作为对Sandy答案的补充添加。

这是一段列出控制台上当前窗口的代码块:

import pygtk
pygtk.require('2.0')
import gtk, wnck

if __name__ == "__main__":
    default = wnck.screen_get_default()

    while gtk.events_pending():
        gtk.main_iteration(False)

    window_list = default.get_windows()
    if len(window_list) == 0:
        print "No Windows Found"
    for win in window_list:
        if win.is_active():
            print '***' + win.get_name()
        else:
            print win.get_name()

感谢Sandy!

3

解析命令行输出通常不是最好的方法,因为你依赖于程序输出不会改变,而这可能会因版本或平台而有所不同。以下是使用Xlib进行操作的方法:

import Xlib.display

screen = Xlib.display.Display().screen()
root_win = screen.root

window_names = []
for window in root_win.query_tree()._data['children']:
    window_name = window.get_wm_name()
    window_names.append(window_name)

print window_names

请注意,此列表将包含您通常不会归类为“窗口”的窗口,但这对于您要做的事情并不重要。

2

来自PyGTK参考文献

gtk.gdk.window_get_toplevels()

gtk.gdk.window_get_toplevels()函数返回一个列表,其中包含默认屏幕上所有已知的顶级窗口。 顶级窗口是根窗口(请参见gtk.gdk.get_default_root_window()函数)的子窗口。


1
它只返回一个窗口 - "('UTF8_STRING', 8, 'wnd.py')",而我有三个打开的gedit窗口。 - john
1
在测试后,我遇到了相同的问题 - 函数的工作方式与参考文献所述的不同。目前最好的选择可能是像NawaMan建议的那样使用调用wmctrl -l;除此之外,我能想到的唯一方法就是直接使用X11模块。 - Donald Harvey

2

我真的不知道如何检查一个窗口是否是GTK窗口。但是如果你想要检查当前有多少个窗口打开,可以尝试使用"wmctrl -l"命令。当然,首先需要安装它。


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