macos 使用 Python 在 Mac OS X 中查找当前活动窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/373020/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-21 05:59:14  来源:igfitidea点击:

Finding the Current Active Window in Mac OS X using Python

pythonobjective-ccocoamacos

提问by Moiz

Is there a way to find the application name of the current active window at a given time on Mac OS X using Python?

有没有办法在 Mac OS X 上使用 Python 在给定时间找到当前活动窗口的应用程序名称?

回答by Dirk Stoop

This should work:

这应该有效:

#!/usr/bin/python

from AppKit import NSWorkspace
activeAppName = NSWorkspace.sharedWorkspace().activeApplication()['NSApplicationName']
print activeAppName

Only works on Leopard, or on Tiger if you have PyObjC installed and happen to point at the right python binary in line one (not the case if you've installed universal MacPython, which you'd probably want to do on Tiger). But Peter's answer with the Carbon way of doing this will probably be quite a bit faster, since importing anything from AppKit in Python takes a while, or more accurately, importing something from AppKit for the first time in a Python process takes a while.

仅适用于 Leopard 或 Tiger,前提是您安装了 PyObjC 并且碰巧指向第一行中正确的 Python 二进制文件(如果您安装了通用 MacPython,则情况并非如此,您可能想在 Tiger 上这样做)。但是 Peter 用 Carbon 的方式来回答可能会快很多,因为在 Python 中从 AppKit 导入任何东西需要一段时间,或者更准确地说,在 Python 过程中第一次从 AppKit 导入东西需要一段时间。

If you need this inside a PyObjC app, what I describe will work great and fast, since you only experience the lag of importing AppKit once. If you need this to work as a command-line tool, you'll notice the performance hit. If that's relevant to you, you're probably better off building a 10 line Foundation command line tool in Xcode using Peter's code as a starting point.

如果您需要在 PyObjC 应用程序中使用它,我所描述的将工作得很好而且很快,因为您只会遇到导入 AppKit 一次的延迟。如果您需要将其用作命令行工具,您会注意到性能下降。如果这与您相关,那么您最好使用 Peter 的代码作为起点在 Xcode 中构建一个 10 行 Foundation 命令行工具。

回答by kmundnic

The method in the accepted answer was deprecated in OS X 10.7+. The current recommended version would be the following:

已接受答案中的方法在 OS X 10.7+ 中已弃用。当前推荐的版本如下:

from AppKit import NSWorkspace
active_app_name = NSWorkspace.sharedWorkspace().frontmostApplication().localizedName()
print(active_app_name)

回答by Peter Hosey

First off, do you want the window or the application name? This isn't Windows—an application process on Mac OS X can have multiple windows. (Furthermore, this has also been true of Windows for a few years now, although I have no idea what the API looks like for that.)

首先,您想要窗口还是应用程序名称?这不是 Windows——Mac OS X 上的应用程序进程可以有多个窗口。(此外,几年来 Windows 也是如此,尽管我不知道 API 是什么样的。)

Second, Carbon or Cocoa?

第二,碳还是可可?

To get the active window in Cocoa:

在 Cocoa 中获取活动窗口:

window = NSApp.mainWindow()

To get the name of your process in Cocoa:

要在 Cocoa 中获取进程的名称:

appName = NSProcessInfo.processInfo().processName()

Edit:Oh, I think I know what you want. The name of the frontmost process, right?

编辑:哦,我想我知道你想要什么。最前面的进程的名字吧?

I don't think there's a way to do it in Cocoa, but here's how to do it in Carbon in C:

我认为在 Cocoa 中没有办法做到这一点,但这里是如何在 C 中的 Carbon 中做到这一点:

ProcessSerialNumber psn = { 0L, 0L };
OSStatus err = GetFrontProcess(&psn);
/*error check*/

CFStringRef processName = NULL;
err = CopyProcessName(&psn, &processName);
/*error check*/

Remember to CFRelease(processName)when you're done with it.

完成后请记住CFRelease(processName)

I'm not sure what that will look like in Python, or if it's even possible. Python doesn't have pointers, which makes that tricky.

我不确定在 Python 中会是什么样子,或者是否有可能。Python 没有指针,这使得这很棘手。

I know PyObjC would translate the latter argument to CopyProcessNameinto err, processName = CopyProcessName(…), but the Carbon bindings don't rely on PyObjC (they're part of core Python 2), and I'm not sure what you do about the PSN either way.

我知道 PyObjC 会将后一个参数转换CopyProcessNameerr, processName = CopyProcessName(…),但是 Carbon 绑定不依赖于 PyObjC(它们是核心 Python 2 的一部分),而且我不确定您对 PSN 的处理方式。

回答by SirVer

I needed the current frontmost application in a Python script that arranges the windows nicely on my screen (see move_window).

我需要一个 Python 脚本中的当前最前面的应用程序,它可以在我的屏幕上很好地排列窗口(请参阅 参考资料move_window)。

Of course, the complete credit goes to Peter! But here is the complete program:

当然,完全归功于彼得!但这是完整的程序:

#include <Carbon/Carbon.h>

int main(int, char) {
    ProcessSerialNumber psn = { 0L, 0L };
    OSStatus err = GetFrontProcess(&psn);

    CFStringRef processName = NULL;
    err = CopyProcessName(&psn, &processName);
    printf("%s\n", CFStringGetCStringPtr(processName, NULL));
    CFRelease(processName);
}

Build with gcc -framework Carbon filename.c

构建 gcc -framework Carbon filename.c