2009-12-30 22 views
20

Wie kann ich meinen Desktop-Hintergrund mit Python ändern?Wie kann ich meinen Desktop-Hintergrund mit Python ändern?

Ich möchte es in Windows und Linux tun.

+2

für die Linux-Hälfte Ihrer Frage (und GNOME-Desktop-Umgebung angenommen wird), könnten Sie einen Blick auf http://oracle.bridgewayconsulting.com.au/~danni/misc/ nehmen wollen change-background-py.html – unutbu

+0

Wer weiß, wie man das in KDE macht? – TheInitializer

Antwort

10

Auf einem GNOME-Desktop, die Sie tun dies in der Regel mit gconf entweder direkt gconftool anrufen oder das gconf Python-Modul. Letzteres ist in der Verbindung von unutbu gegeben. Die erste Methode könnte so gemacht werden.

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

Für Ubuntu 11.04 scheint das nicht mehr zu funktionieren. Die gconf-Einstellung ändert sich, aber der Hintergrund aktualisiert das neue Bild nicht. – hobs

+0

Ich benutze 11.04, und ich habe gerade ein Skript geschrieben, das Bilder in einem Ordner durchläuft, und ich habe dieses Snippet verwendet. Hat gut für mich funktioniert. Allerdings führe ich den Befehl mit os.system (command) – MikeVaughan

2

Unter Windows benötigen Sie einige Tricks mit pywin32 und the windows API, auf 'linux' hängt die Antwort davon ab, welcher Desktop läuft - KDE, Gnome oder etwas exotischer. Unter KDE (und vielleicht Gnome) können Sie wahrscheinlich eine Nachricht mit D-Bus senden, die Sie ohne neue Bibliotheken über das Kommandozeilenwerkzeug dbus-send erstellen könnten.

Die andere Option wäre, den Desktop-Hintergrund in eine Datei zu setzen, die Sie dann aus Python bearbeiten/ersetzen - aber das wird wahrscheinlich nur zu einer Änderung führen, wenn sich der Benutzer anmeldet

32

Unter Windows mit python2.. 5 oder höher, verwenden Sie ctypes, um user32.dll zu laden, und rufen Sie SystemParametersInfo() mit Aktion SPI_SETDESKWALLPAPER auf.

Zum Beispiel:

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

+1 ctypes ist vorzuziehen pywin32 – James

+2

schien nicht mit einem .jpg zu arbeiten, arbeitet mit einem .bmp tho (auf xp) – Noelkd

+2

ich erfolgreich ein jpg auf win 7 – CrazyPenguin

6

In Gnom, ist es wahrscheinlich vorzuziehen, die Python-Bindung von gconf direkt zu verwenden:

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

Zum einen Import ctypes: es gibt Ihnen auf Windows-Komponenten zugreifen, wie der Bildschirmschoner, Hintergrundbilder, etc. .

nennen Dann ctypes.windll.user32.SystemParametersInfoA(a,b,c,d):

a = 20

b = 0

c = Die komplette Pfad des Bildes. Not just the path from the active directory

d = 0

9

Ich verwende die folgende Methode in einer meiner ersten Projekte:

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.") 

Die get_desktop_environment Methode hat in another thread veröffentlicht.

+1

Statt der 'get_home_dir()' Funktion können Sie einfach 'os.path.expanduser ('~')' –

1

das Hintergrundbild des Desktops zu ändern

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

es funktionierte gut für mich. windows10, python27

2

Es gibt einen Unterschied was SystemParametersInfo Methode aufgerufen werden basierend auf was, wenn Sie auf 64-Bit oder 32-Bit-Betriebssystem ausgeführt werden. Für 64-Bit haben Sie SystemParametersInfoW (Unicode) und für 32-Bit-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

Dies ist Unsinn. Die Wahl von ASCII oder Unicode ist völlig unabhängig davon, ob Sie 32-Bit- oder 64-Bit-Windows ausführen. (Sie mussten ASCII unter 16-Bit-Windows und Windows 95/98/ME verwenden, aber Windows NT hat immer Unicode unterstützt, sowohl 32-Bit- als auch 64-Bit-Versionen.) –

+0

@HarryJohnston dann erklären Sie 'SystemParametersInfoA' funktioniert nicht unter Windows 10 64-Bit? – Johnny

+1

@Johnny, ich habe es gerade ausprobiert, und es funktioniert perfekt für mich. Das ist von C, wohlgemerkt, also ist es immer noch möglich, dass es irgendeine Python-bezogene Seltsamkeit gibt, die irgendwie von der Bissigkeit des Betriebssystems abhängt, obwohl das sehr unwahrscheinlich erscheint. Wenn man sich die Ctypes-Dokumentation anschaut, sollte es * nur davon abhängen, ob Sie Python 2 oder Python 3 verwenden. –

6

für Python3.5, SystemParametersInfoA funktioniert nicht verwenden.Verwenden Sie SystemParametersInfoW.

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

Ist es Python oder die Arten von Windows verwendet? – Johnny

+0

Python2 verwendet ** SystemParametersInfoA ** und Python3 verwendet ** SystemParametersInfoW ** – mesksr

Verwandte Themen