核心要点
dir()
函数和pyobjc文档,可以导航macOS API并执行任何可以用Objective-C完成的任务。本文节选自《实用Python》,Stuart探讨了使用Python控制Windows操作系统的方法。
在Mac上工作时,我们可以使用pyobjc(Python到Objective-C的桥接)来控制系统几乎所有方面。Apple通过AppKit模块使大多数操作系统可控,而pyobjc使Python可以访问所有这些功能。如果我们已经知道使用AppKit的方法来完成我们想要做的事情,那么这将非常有用,但只需稍加探索,就可以遍历操作系统API。
让我们尝试一个示例。首先,我们需要pyobjc,可以使用pip install pyobjc
安装。这将安装整个操作系统API桥接列表,允许访问macOS的各种方面。目前,我们将考虑AppKit,它是用于构建和控制Mac桌面上的正在运行的应用程序的工具。
我们可以使用AppKit列出当前正在运行的所有应用程序:
<code class="language-python">>>> from AppKit import NSWorkspace >>> NSWorkspace.sharedWorkspace().runningApplications() ( "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", ) >>></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></code>
这将提供一个很长的NSRunningApplication对象列表。每个对象都对应于当前在桌面上运行的特定应用程序。许多是“不可见”的应用程序(正在运行但并非一定显示窗口的应用程序),但其他一些是我们可能认为是实际应用程序的应用程序——例如Safari、Terminal等等。NSRunningApplication在developer.apple.com上有文档记录,可以在其中查看其属性。例如,每个应用程序都有一个localizedName
和一个bundleIdentifier
:
<code class="language-python">>>> for nsapp in NSWorkspace.sharedWorkspace().runningApplications(): ... print(f"{nsapp.localizedName()} -> {nsapp.bundleIdentifier()}") ... loginwindow -> com.apple.loginwindow BackgroundTaskManagementAgent -> com.apple.backgroundtaskmanagement.agent WindowManager -> com.apple.WindowManager CoreLocationAgent -> com.apple.CoreLocationAgent Terminal -> com.apple.Terminal Safari -> com.apple.Safari Spotlight -> com.apple.Spotlight Finder -> com.apple.finder</code>
我们还可以看到NSRunningApplication对象有一个activate
函数,我们可以调用它来激活该应用程序,就像我们单击Dock中的图标一样。因此,要查找Safari然后激活它,我们将使用该activate
函数。对activate
的调用需要options
的值,如文档所述,这也需要从AppKit导入:
<code class="language-python">>>> from AppKit import NSWorkspace, NSApplicationActivateIgnoringOtherApps >>> safari_list = [x for x in NSWorkspace.sharedWorkspace().runningApplications() ... if x.bundleIdentifier() == 'com.apple.Safari'] >>> safari = safari_list[0] >>> safari.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)</code>
现在Safari已激活。
查找macOS API的Python版本
查找与Objective-C名称对应的Python名称可能有点棘手。如上面的代码所示,Objective-C的activate
函数在Python中称为activateWithOptions_
。有一套关于此名称转换的规则,pyobjc文档对此进行了说明,但有时使用Python自己的dir()
函数来显示对象的全部属性,然后选择看起来最合理的属性会更快:
<code class="language-python">>>> from AppKit import NSWorkspace >>> NSWorkspace.sharedWorkspace().runningApplications() ( "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", "<nsrunningapplication: lsasn:="">", ) >>></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></nsrunningapplication:></code>
哎呀!我们的safari(NSRunningApplication实例)有452个属性!好吧,我们想要的那个可能被称为类似“activate”的东西,所以:
<code class="language-python">>>> for nsapp in NSWorkspace.sharedWorkspace().runningApplications(): ... print(f"{nsapp.localizedName()} -> {nsapp.bundleIdentifier()}") ... loginwindow -> com.apple.loginwindow BackgroundTaskManagementAgent -> com.apple.backgroundtaskmanagement.agent WindowManager -> com.apple.WindowManager CoreLocationAgent -> com.apple.CoreLocationAgent Terminal -> com.apple.Terminal Safari -> com.apple.Safari Spotlight -> com.apple.Spotlight Finder -> com.apple.finder</code>
啊哈!所以activateWithOptions_
是我们需要调用的函数的名称。类似地,我们要传递给该函数的选项的名称在AppKit本身中:
<code class="language-python">>>> from AppKit import NSWorkspace, NSApplicationActivateIgnoringOtherApps >>> safari_list = [x for x in NSWorkspace.sharedWorkspace().runningApplications() ... if x.bundleIdentifier() == 'com.apple.Safari'] >>> safari = safari_list[0] >>> safari.activateWithOptions_(NSApplicationActivateIgnoringOtherApps)</code>
这个过程有时会感觉有点探索性,但是也可以从Python执行Objective-C可以执行的任何操作。
本文节选自《实用Python》,可在SitePoint Premium和电子书零售商处购买。
关于使用Python控制MacOS的常见问题解答(FAQ)
AppKit是macOS SDK中的一个框架,其中包含在macOS应用程序中实现图形化、事件驱动的用户界面所需的所有对象。它提供广泛的类和函数,用于创建和管理应用程序窗口、处理用户输入、绘制图形以及执行与用户界面相关的其他任务。在Python中,您可以使用PyObjC桥接来访问AppKit和其他Objective-C框架。这允许您编写可以控制macOS应用程序、操作窗口和与系统服务交互的Python脚本。
PyObjC是一个Python到Objective-C的桥接,允许您使用Python编写功能齐全的macOS应用程序。您可以使用Python包安装程序pip来安装它。打开终端窗口并键入以下命令:pip install pyobjc
。这将下载并安装PyObjC模块及其依赖项。安装完成后,您可以使用import objc
在Python脚本中导入该模块。
此错误通常表示AppKit模块未安装或在您的Python环境中找不到。首先,确保您已安装PyObjC模块(其中包括AppKit)。如果您已安装PyObjC但仍然收到此错误,则您可能正在使用未安装PyObjC的不同Python环境。在这种情况下,您需要在正确的Python环境中安装PyObjC,或切换到已安装PyObjC的Python环境。
使用PyObjC桥接,您可以使用Python通过发送AppleScript命令或使用脚本桥来控制macOS应用程序。例如,您可以启动应用程序、操作窗口、发送击键并执行其他任务。这需要很好地理解Python和AppleScript,以及应用程序的脚本接口。
AppKit框架提供了一些用于处理窗口的类,例如NSWindow
和NSApplication
。您可以使用这些类来获取所有打开窗口的列表,将窗口置于最前面,调整窗口大小或移动窗口,以及执行其他与窗口相关的任务。这需要使用PyObjC桥接从Python访问AppKit类。
是的,您可以使用Python和PyObjC桥接与macOS中的各种系统服务交互。例如,您可以使用NSWorkspace
类打开URL、启动应用程序以及执行与用户的workspace相关的其他任务。您还可以使用NSNotificationCenter
类来发布和观察通知,这允许您的脚本响应系统事件。
您可以使用AppKit框架的NSEvent
类来创建和发布键盘事件,这实际上允许您从Python脚本发送击键。这需要很好地理解NSEvent
类和键盘事件类型,以及您要按下的键的键码。
是的,AppKit框架提供了一些用于绘制图形的类,例如NSGraphicsContext
、NSBezierPath
和NSColor
。您可以使用这些类来绘制线条、形状和图像,设置绘图颜色以及执行其他绘图任务。这需要使用PyObjC桥接从Python访问AppKit类。
AppKit框架提供了一些用于处理用户输入的类,例如NSEvent
和NSResponder
。您可以使用这些类来获取鼠标事件、键盘事件和其他类型的用户输入。这需要使用PyObjC桥接从Python访问AppKit类。
是的,使用PyObjC桥接,您可以使用Python编写功能齐全的macOS应用程序。这包括使用窗口、按钮和其他控件创建图形用户界面、处理用户输入、绘制图形以及与系统服务交互。但是,这需要很好地理解Python和macOS SDK,以及AppKit框架和其他Objective-C框架。
以上是快速提示:用Python控制MacOS的详细内容。更多信息请关注PHP中文网其他相关文章!