在X中获取活动窗口标题

时间:2010-10-21 02:52:32

标签: python linux pyqt4

我正在尝试获取活动窗口的标题。该应用程序是一个后台任务,因此如果用户打开Eclipse,该函数将返回“Eclipse - blabla”,因此它不会获得我自己窗口的窗口标题。我正在使用PyQt4在Python 2.6中开发它。

我现在的解决方案,从SO的旧答案中借用并略微修改,看起来像这样:

def get_active_window_title():
    title = ''
    root_check = ''

    root = Popen(['xprop', '-root'],  stdout=PIPE)

    if root.stdout != root_check:
        root_check = root.stdout

        for i in root.stdout:
            if '_NET_ACTIVE_WINDOW(WINDOW):' in i:
                id_ = i.split()[4]
                id_w = Popen(['xprop', '-id', id_], stdout=PIPE)

        for j in id_w.stdout:
            if 'WM_ICON_NAME(STRING)' in j:
                if title != j.split()[2]:
                    return j.split("= ")[1].strip(' \n\"')

它适用于大多数窗口,但不是全部。例如,它无法找到我的kopete聊天窗口,或者我正在开发的应用程序的名称。

我的下一次尝试看起来像这样:

def get_active_window_title(self):
    screen = wnck.screen_get_default()
    if screen == None:
        return "Could not get screen"
    window = screen.get_active_window()
    if window == None:
        return "Could not get window"
    title = window.get_name()
    return title;

但由于某些原因,窗口始终为无。

有人有更好的方法获取当前窗口标题,或者如何修改我的方法之一,适用于所有窗口?

编辑:

如果有人想知道这是我发现的方式似乎适用于所有窗口。

def get_active_window_title(self):
    root_check = ''
    root = Popen(['xprop', '-root'],  stdout=PIPE)

    if root.stdout != root_check:
        root_check = root.stdout

        for i in root.stdout:
            if '_NET_ACTIVE_WINDOW(WINDOW):' in i:
                id_ = i.split()[4]
                id_w = Popen(['xprop', '-id', id_], stdout=PIPE)
        id_w.wait()
        buff = []
        for j in id_w.stdout:
            buff.append(j)

        for line in buff:
            match = re.match("WM_NAME\((?P<type>.+)\) = (?P<name>.+)", line)
            if match != None:
                type = match.group("type")
                if type == "STRING" or type == "COMPOUND_TEXT":
                    return match.group("name")
        return "Active window not found"

5 个答案:

答案 0 :(得分:8)

xdotool可以做到这一点。

xdotool getactivewindow

答案 1 :(得分:8)

我稍微修改了你的解决方案,因此它应该更有效地运行(它将参数传递给xprop,因此只返回它需要的数据)。另外,我不确定是否有必要缓冲xprop的输出,所以我把它拿出来了。如果由于某种原因它找不到活动窗口,它也应该正确返回“找不到活动窗口”。

def get_active_window_title(self):
    root = Popen(['xprop', '-root', '_NET_ACTIVE_WINDOW'], stdout=PIPE)

    for line in root.stdout:
        m = re.search('^_NET_ACTIVE_WINDOW.* ([\w]+)$', line)
        if m != None:
            id_ = m.group(1)
            id_w = Popen(['xprop', '-id', id_, 'WM_NAME'], stdout=PIPE)
            break

    if id_w != None:
        for line in id_w.stdout:
            match = re.match("WM_NAME\(\w+\) = (?P<name>.+)$", line)
            if match != None:
                return match.group("name")

    return "Active window not found"

答案 2 :(得分:1)

您可以使用xdotool获取有效窗口标题:

$ xdotool getactivewindow getwindowname

答案 3 :(得分:0)

我看到这个问题现在有点尘土飞扬,对Python 2的支持也已接近其计划的生命周期,所以我想我想提一个更多的Python 3'ic版本。

实际上,它可能比3种样式更好-在Python 3中,“通过with语句将Popen对象作为上下文管理器来支持:退出时,标准文件描述符被关闭,过程等待”。 / p>

因此,对于较新的Python,以下内容可能更合适,并且资源消耗更少:

(同样,如果没有with,您可能会遇到“打开文件过多”的问题-我当然是用困难的方式发现的:)-您是否应该经常查询窗口标题? Ubuntu〜16。)

    with Popen(['xprop', '-root', '_NET_ACTIVE_WINDOW'], stdout=PIPE) as root:
        for line in root.stdout:
            line = str(line, encoding="UTF-8")

            m = re.search('^_NET_ACTIVE_WINDOW.* ([\w]+)$', line)
            if m is not None:
                id_ = m.group(1)
                with Popen(['xprop', '-id', id_, 'WM_NAME'],
                           stdout=PIPE) as id_w:
                    for line in id_w.stdout:
                        line = str(line, encoding="UTF-8")
                        match = re.match("WM_NAME\(\w+\) = \"(?P<name>.+)\"$",
                                         line)
                    if match is not None:
                        return match.group("name")
                break
    return "Active window not found"

答案 4 :(得分:0)

这太晚了,无法使用,但它确实可以工作,并且我有使用wnck的程序。

wnck工作之前,screen.force_update()示例需要调用wnck。否则,wnck在屏幕上没有任何有关窗口的信息。那就是:

def get_active_window_title(self):
    screen = wnck.screen_get_default()
    if screen is None:
        return "Could not get screen"
    screen.force_update()
    window = screen.get_active_window()
    if window is None:
        return "Could not get window"
    title = window.get_name()
    return title