2009-12-30 137 views
20

如何用python更改我的桌面背景?如何用python更改我的桌面背景?

我想在Windows和Linux中都這樣做。

+2

對於你的問題的Linux的一半,(假設一個GNOME桌面環境),你可能想看看http://oracle.bridgewayconsulting.com.au/~danni/misc/ change-background-py.html – unutbu

+0

任何人都知道如何在KDE中做到這一點? – TheInitializer

回答

10

在GNOME桌面,你通常會做此用的gconf,無論是直接調用gconftool或使用的gconf Python模塊。後者是由unutbu給出的鏈接。第一種方法可以像這樣完成。

import commands 
command = "gconftool-2 --set /desktop/gnome/background/picture_filename --type string '/path/to/file.jpg'" 
status, output = commands.getstatusoutput(command) # status=0 if success 
+0

對於Ubuntu 11.04,這似乎不再有效。 gconf設置會更改,但背景不會刷新到新圖像。 – hobs

+0

我正在使用11.04,並且我剛剛編寫了一個腳本,它可以循環顯示文件夾中的圖像,並使用此代碼段。爲我工作得很好。但是,我使用os.system(command) – MikeVaughan

2

在windows上,你需要一些技巧與pywin32the windows API,'linux'上的答案將取決於哪個桌面正在運行 - KDE,Gnome或更奇特的東西。在KDE(也可能是Gnome)下,您可以使用D-Bus發送消息,您可以通過使用命令行工具dbus-send在不包括任何新庫的情況下發送消息。

另一種選擇是設置桌面壁紙一個文件,你再編輯/蟒蛇代替 - 但這可能只會導致變化時

32

用戶登錄在Windows上使用python2。 5或更高版本,請使用ctypes加載user32.dll並使用SPI_SETDESKWALLPAPER操作調用SystemParametersInfo()

例如:

import ctypes 
SPI_SETDESKWALLPAPER = 20 
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, "image.jpg" , 0) 
+1

+1 ctypes比pywin32更可取 – James

+2

似乎無法與.jpg一起使用,使用.bmp tho(在xp上) – Noelkd

+2

我成功在win上使用jpg 7 – CrazyPenguin

6

在GNOME中,它可能是最好使用Python直接的gconf的結合:

import gconf 
conf = gconf.client_get_default() 
conf.set_string('/desktop/gnome/background/picture_filename','/path/to/filename.jpg') 
9

我用下面的方法在我最初的項目之一:

def set_wallpaper(self,file_loc, first_run): 
     # Note: There are two common Linux desktop environments where 
     # I have not been able to set the desktop background from 
     # command line: KDE, Enlightenment 
     desktop_env = self.get_desktop_environment() 
     try: 
      if desktop_env in ["gnome", "unity", "cinnamon"]: 
       uri = "'file://%s'" % file_loc 
       try: 
        SCHEMA = "org.gnome.desktop.background" 
        KEY = "picture-uri" 
        gsettings = Gio.Settings.new(SCHEMA) 
        gsettings.set_string(KEY, uri) 
       except: 
        args = ["gsettings", "set", "org.gnome.desktop.background", "picture-uri", uri] 
        subprocess.Popen(args) 
      elif desktop_env=="mate": 
       try: # MATE >= 1.6 
        # info from http://wiki.mate-desktop.org/docs:gsettings 
        args = ["gsettings", "set", "org.mate.background", "picture-filename", "'%s'" % file_loc] 
        subprocess.Popen(args) 
       except: # MATE < 1.6 
        # From https://bugs.launchpad.net/variety/+bug/1033918 
        args = ["mateconftool-2","-t","string","--set","/desktop/mate/background/picture_filename",'"%s"' %file_loc] 
        subprocess.Popen(args) 
      elif desktop_env=="gnome2": # Not tested 
       # From https://bugs.launchpad.net/variety/+bug/1033918 
       args = ["gconftool-2","-t","string","--set","/desktop/gnome/background/picture_filename", '"%s"' %file_loc] 
       subprocess.Popen(args) 
      ## KDE4 is difficult 
      ## see http://blog.zx2c4.com/699 for a solution that might work 
      elif desktop_env in ["kde3", "trinity"]: 
       # From http://ubuntuforums.org/archive/index.php/t-803417.html 
       args = 'dcop kdesktop KBackgroundIface setWallpaper 0 "%s" 6' % file_loc 
       subprocess.Popen(args,shell=True) 
      elif desktop_env=="xfce4": 
       #From http://www.commandlinefu.com/commands/view/2055/change-wallpaper-for-xfce4-4.6.0 
       if first_run: 
        args0 = ["xfconf-query", "-c", "xfce4-desktop", "-p", "/backdrop/screen0/monitor0/image-path", "-s", file_loc] 
        args1 = ["xfconf-query", "-c", "xfce4-desktop", "-p", "/backdrop/screen0/monitor0/image-style", "-s", "3"] 
        args2 = ["xfconf-query", "-c", "xfce4-desktop", "-p", "/backdrop/screen0/monitor0/image-show", "-s", "true"] 
        subprocess.Popen(args0) 
        subprocess.Popen(args1) 
        subprocess.Popen(args2) 
       args = ["xfdesktop","--reload"] 
       subprocess.Popen(args) 
      elif desktop_env=="razor-qt": #TODO: implement reload of desktop when possible 
       if first_run: 
        desktop_conf = configparser.ConfigParser() 
        # Development version 
        desktop_conf_file = os.path.join(self.get_config_dir("razor"),"desktop.conf") 
        if os.path.isfile(desktop_conf_file): 
         config_option = r"screens\1\desktops\1\wallpaper" 
        else: 
         desktop_conf_file = os.path.join(self.get_home_dir(),".razor/desktop.conf") 
         config_option = r"desktops\1\wallpaper" 
        desktop_conf.read(os.path.join(desktop_conf_file)) 
        try: 
         if desktop_conf.has_option("razor",config_option): #only replacing a value 
          desktop_conf.set("razor",config_option,file_loc) 
          with codecs.open(desktop_conf_file, "w", encoding="utf-8", errors="replace") as f: 
           desktop_conf.write(f) 
        except: 
         pass 
       else: 
        #TODO: reload desktop when possible 
        pass 
      elif desktop_env in ["fluxbox","jwm","openbox","afterstep"]: 
       #http://fluxbox-wiki.org/index.php/Howto_set_the_background 
       # used fbsetbg on jwm too since I am too lazy to edit the XML configuration 
       # now where fbsetbg does the job excellent anyway. 
       # and I have not figured out how else it can be set on Openbox and AfterSTep 
       # but fbsetbg works excellent here too. 
       try: 
        args = ["fbsetbg", file_loc] 
        subprocess.Popen(args) 
       except: 
        sys.stderr.write("ERROR: Failed to set wallpaper with fbsetbg!\n") 
        sys.stderr.write("Please make sre that You have fbsetbg installed.\n") 
      elif desktop_env=="icewm": 
       # command found at http://urukrama.wordpress.com/2007/12/05/desktop-backgrounds-in-window-managers/ 
       args = ["icewmbg", file_loc] 
       subprocess.Popen(args) 
      elif desktop_env=="blackbox": 
       # command found at http://blackboxwm.sourceforge.net/BlackboxDocumentation/BlackboxBackground 
       args = ["bsetbg", "-full", file_loc] 
       subprocess.Popen(args) 
      elif desktop_env=="lxde": 
       args = "pcmanfm --set-wallpaper %s --wallpaper-mode=scaled" % file_loc 
       subprocess.Popen(args,shell=True) 
      elif desktop_env=="windowmaker": 
       # From http://www.commandlinefu.com/commands/view/3857/set-wallpaper-on-windowmaker-in-one-line 
       args = "wmsetbg -s -u %s" % file_loc 
       subprocess.Popen(args,shell=True) 
      ## NOT TESTED BELOW - don't want to mess things up ## 
      #elif desktop_env=="enlightenment": # I have not been able to make it work on e17. On e16 it would have been something in this direction 
      # args = "enlightenment_remote -desktop-bg-add 0 0 0 0 %s" % file_loc 
      # subprocess.Popen(args,shell=True) 
      #elif desktop_env=="windows": #Not tested since I do not run this on Windows 
      # #From https://stackoverflow.com/questions/1977694/change-desktop-background 
      # import ctypes 
      # SPI_SETDESKWALLPAPER = 20 
      # ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, file_loc , 0) 
      #elif desktop_env=="mac": #Not tested since I do not have a mac 
      # #From https://stackoverflow.com/questions/431205/how-can-i-programatically-change-the-background-in-mac-os-x 
      # try: 
      #  from appscript import app, mactypes 
      #  app('Finder').desktop_picture.set(mactypes.File(file_loc)) 
      # except ImportError: 
      #  #import subprocess 
      #  SCRIPT = """/usr/bin/osascript<<END 
      #  tell application "Finder" to 
      #  set desktop picture to POSIX file "%s" 
      #  end tell 
      #  END""" 
      #  subprocess.Popen(SCRIPT%file_loc, shell=True) 
      else: 
       if first_run: #don't spam the user with the same message over and over again 
        sys.stderr.write("Warning: Failed to set wallpaper. Your desktop environment is not supported.") 
        sys.stderr.write("You can try manually to set Your wallpaper to %s" % file_loc) 
       return False 
      return True 
     except: 
      sys.stderr.write("ERROR: Failed to set wallpaper. There might be a bug.\n") 
      return False 

    def get_config_dir(self, app_name=APP_NAME): 
     if "XDG_CONFIG_HOME" in os.environ: 
      confighome = os.environ['XDG_CONFIG_HOME'] 
     elif "APPDATA" in os.environ: # On Windows 
      confighome = os.environ['APPDATA'] 
     else: 
      try: 
       from xdg import BaseDirectory 
       confighome = BaseDirectory.xdg_config_home 
      except ImportError: # Most likely a Linux/Unix system anyway 
       confighome = os.path.join(self.get_home_dir(),".config") 
     configdir = os.path.join(confighome,app_name) 
     return configdir 

    def get_home_dir(self): 
     if sys.platform == "cygwin": 
      home_dir = os.getenv('HOME') 
     else: 
      home_dir = os.getenv('USERPROFILE') or os.getenv('HOME') 
     if home_dir is not None: 
      return os.path.normpath(home_dir) 
     else: 
      raise KeyError("Neither USERPROFILE or HOME environment variables set.") 

的get_desktop_environment方法已經公佈​​。

+1

執行命令,而不是'get_home_dir()'函數,你可以使用'os.path.expanduser('〜')' –

1

更改桌面

import ctypes 
    import os 
    SPI_SETDESKWALLPAPER = 20 
    ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, 'your image path', 3) 
    #'C:\\Users\\Public\\Pictures\\abc.jpg' 

的背景圖像,它爲我工作得很好。 windows10,python27

2

如果你在64位或32位操作系統上運行,根據什麼調用SystemParametersInfo方法是有區別的。對於64位,你必須使用SystemParametersInfoW(統一)和32位SystemParametersInfoA(ANSI)

import struct 
import ctypes 


SPI_SETDESKWALLPAPER = 20 
WALLPAPER_PATH = 'C:\\your_file_name.jpg' 


def is_64_windows(): 
    """Find out how many bits is OS. """ 
    return struct.calcsize('P') * 8 == 64 


def get_sys_parameters_info(): 
    """Based on if this is 32bit or 64bit returns correct version of SystemParametersInfo function. """ 
    return ctypes.windll.user32.SystemParametersInfoW if is_64_windows() \ 
     else ctypes.windll.user32.SystemParametersInfoA 


def change_wallpaper(): 
    sys_parameters_info = get_sys_parameters_info() 
    r = sys_parameters_info(SPI_SETDESKWALLPAPER, 0, WALLPAPER_PATH, 3) 

    # When the SPI_SETDESKWALLPAPER flag is used, 
    # SystemParametersInfo returns TRUE 
    # unless there is an error (like when the specified file doesn't exist). 
    if not r: 
     print(ctypes.WinError()) 


change_wallpaper() 
+1

這是無稽之談。 ASCII或Unicode的選擇與您運行的是32位還是64位Windows完全無關。 (您必須在16位Windows和Windows 95/98/ME上使用ASCII,但Windows NT始終支持Unicode,包括32位和64位版本。) –

+0

@HarryJohnston那麼您如何解釋'SystemParametersInfoA'不適用於Windows 10 64位? – Johnny

+1

@Johnny,我剛剛嘗試過,它對我來說非常好。這是來自C,請注意,所以它仍然是可能的,即某些與Python相關的奇怪事情在某種程度上取決於操作系統的位置,儘管這似乎不太可能。查看ctypes文檔,它*應該*僅取決於您是使用Python 2還是使用Python 3. –

6

對於Python3.5,SystemParametersInfoA不起作用。使用SystemParametersInfoW。

import ctypes 
ctypes.windll.user32.SystemParametersInfoW(20, 0, "absolute path" , 0) 
+0

它是Python還是使用Windows的類型? – Johnny

+0

Python2使用** SystemParametersInfoA **,Python3使用** SystemParametersInfoW ** – mesksr