如何在Mac OS X中通过编程方式更改背景?

38

我如何在Mac OS X中以编程的方式更改桌面背景? 我想使用Python,但我对任何可能的方法都感兴趣。 我能连接到终端并调用特定命令吗?


在您自己的计算机上这样做是可以的,甚至可以让其他人轻松设置背景。但是,请不要将其编写为自动设置背景的应用程序的一部分;桌面是供用户选择的,从未是应用程序在未经用户明确许可的情况下更改的地方。 - Jonathan Leffler
3
除了办公室恶作剧的情况外,其他情况均不适用。 - Nick T
12个回答

45

如果你从Python中安装了appscriptsudo easy_install appscript),你可以轻松执行以下操作:

from appscript import app, mactypes
app('Finder').desktop_picture.set(mactypes.File('/your/filename.jpg'))
否则,这个 applescript 将会改变桌面背景。
tell application "Finder"
    set desktop picture to POSIX file "/your/filename.jpg"
end tell

您可以使用osascript从命令行运行它,或者使用类似以下的Python代码:

import subprocess

SCRIPT = """/usr/bin/osascript<<END
tell application "Finder"
set desktop picture to POSIX file "%s"
end tell
END"""

def set_desktop_background(filename):
    subprocess.Popen(SCRIPT%filename, shell=True)

1
请注意,在Mac OS X 10.7中,这只会更改当前桌面的桌面图像,而不是所有桌面的图像! - Robin
4
请注意,这仅会影响具有菜单栏的监视器的桌面,而不会影响其他监视器上的桌面。有没有办法使其影响其他桌面? - iconoclast
有一个[一行解决方案](https://dev59.com/CHRC5IYBdhLWcg3wCMnX#431384),可以在不用将osascript包装在Python脚本中的情况下运行。 - aculich
2
AppleScript可以简化为一行,如下:tell application "Finder" to set desktop picture to POSIX file "/your/filename.jpg",您可以在终端中使用以下命令运行它:osascript -e 'tell application "Finder" to set desktop picture to POSIX file "/your/filename.jpg"' - user137369
我添加了一个答案,可以在不使用killall Dock的情况下完成此操作。 - tnychn
显示剩余3条评论

21

如果您正在为当前用户执行此操作,您可以在 shell 中运行:

defaults write com.apple.desktop Background '{default = {ImageFilePath = "/Library/Desktop Pictures/Black & White/Lightning.jpg"; };}'

或者,以 root 身份,为另一个用户执行:

/usr/bin/defaults write /Users/joeuser/Library/Preferences/com.apple.desktop Background '{default = {ImageFilePath = "/Library/Desktop Pictures/Black & White/Lightning.jpg"; };}'
chown joeuser /Users/joeuser/Library/Preferences/com.apple.desktop.plist

你当然会想要替换图像文件名和用户名。

新设置将在Dock启动时生效,无论是在登录时还是在你...

killall Dock

[基于其他帖子的发帖内容,并根据Matt Miller的回答的信息。]


1
这个解决方案在 Mavericks 上已经不再适用了,但有另一个一行代码的解决方案可以解决问题。链接 - aculich

12

我有一个相同的问题,但是我想要更改所有附加的显示器的壁纸。这里是一个使用appscript(上面提到的;sudo easy_install appscript)完成此操作的Python脚本。

#!/usr/bin/python

from appscript import *
import argparse

def __main__():
  parser = argparse.ArgumentParser(description='Set desktop wallpaper.')
  parser.add_argument('file', type=file, help='File to use as wallpaper.')
  args = parser.parse_args()
  f = args.file
  se = app('System Events')
  desktops = se.desktops.display_name.get()
  for d in desktops:
    desk = se.desktops[its.display_name == d]
    desk.picture.set(mactypes.File(f.name))


__main__()

6

dF.的答案 基础上,您可以使用Apple Script而无需使用Finder,并且可以将其应用于多个桌面。

要设置桌面i 的壁纸(桌面编号从1开始):

tell application "System Events"
    set currDesktop to item i of desktop
    set currDesktop's picture to "image_path"
end tell

这是我最终用Python实现的方式:
SET_DESKTOP_IMAGE_WRAPPER = """/usr/bin/osascript<<END
tell application "System Events"
{}
end tell
END"""

SET_DESKTOP_IMAGE = """
set currDesktop to item {idx} of desktops
set currDesktop's picture to "{image_path}"
"""

def set_wallpapers(images):
    """ images is an array of file paths of desktops """

    script_contents = ""
    for i, img in enumerate(images):
        idx = i+1
        script_contents += SET_DESKTOP_IMAGE.format(idx=idx, image_path=img)

    script = SET_DESKTOP_IMAGE_WRAPPER.format(script_contents)
    subprocess.check_call(script, shell=True)

有时候,桌面图片不能立即显示。我不知道为什么会发生这种情况,但重新启动dock可以解决它。 要使用Python执行此操作:
subprocess.check_call("killall Dock", shell=True)

顺便提一下,您可以使用以下AppleScript代码获取系统上的桌面数量:

tell application "System Events"
    get the number of desktops
end tell

你可以使用 subprocess.check_output 来获取输出结果。


4

1
“thingsthatwork.net”链接已不再可用。 - Saurav Maheshkar

3
“Mavericks的一行解决方案是:”
osascript -e 'tell application "Finder" to set desktop picture to POSIX file "/Library/Desktop Pictures/Earth Horizon.jpg"'

就像许多其他答案一样,如果我在全屏应用程序中运行它,这个方法也无效。 - undefined

2

把以下内容放在你的~/.bashrc中:

function wallpaper() {
    wallpaper_script="tell application \"Finder\" to set desktop picture to POSIX file \"$HOME/$1\""
    osascript -e $wallpaper_script 
}

使用方式如下:

wallpaper /path/to/image.png

将您的回答与上面的@0xADADA相结合,现在终于有一种方法可以在使用多个显示器时将所有桌面背景旋转到同一图像。耶! - Chris Smith

2
你可以通过从Python脚本中运行Swift脚本来完成此操作,而无需使用killall Dock命令。请创建一个名为chwall.swift的文件,并将以下代码复制到其中:
#!/usr/bin/env swift

import Cocoa

do {
    // get the main (currently active) screen
    if let screen = NSScreen.main {
        // get path to wallpaper file from first command line argument
        let url = URL(fileURLWithPath: CommandLine.arguments[1])
        // set the desktop wallpaper
        try NSWorkspace.shared.setDesktopImageURL(url, for: screen, options: [:])
    }
} catch {
    print(error)
}


现在使用Python中的subprocess运行上述的chwall.swift文件。
import subprocess

subprocess.run(["./chwall.swift", "/path/to/your/wallpaper/file.png"])

如果我在全屏应用程序中运行它,这将不起任何作用。 - undefined

2

默认情况下,有一组高质量图像在以下位置:

/Library/Desktop Pictures/

为了在所有桌面上自动选择其中一个,而不依赖第三方软件:
osascript -e 'tell application "System Events" to set picture of every desktop to "/Library/Desktop Pictures/Solid Colors/Stone.png"'

1

补充Matt Miller的回答:您可以使用subprocess.call()来执行shell命令,如下所示:

import subprocess
subprocess.call(["defaults", "write", "com.apple.Desktop", "background", ...])

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