2009-12-30 47 views
20

¿Cómo puedo cambiar el fondo de mi escritorio con python?¿Cómo puedo cambiar el fondo de mi escritorio con python?

Quiero hacerlo tanto en Windows como en Linux.

+2

Para el Linux mitad de su pregunta, (y suponiendo un entorno de escritorio GNOME), es posible que desee echar un vistazo a http://oracle.bridgewayconsulting.com.au/~danni/misc/ change-background-py.html – unutbu

+0

¿Alguien sabe cómo hacer esto en KDE? – TheInitializer

Respuesta

10

En un entorno de escritorio GNOME, que suele hacer esto con gconf, o bien llamando directamente gconftool o utilizando el módulo de gconf pitón. Este último está en el enlace dado por unutbu. El primer método podría hacerse así.

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

Para Ubuntu 11.04 esto ya no parece funcionar. La configuración de gconf cambia, pero el fondo no se actualiza a la nueva imagen. – hobs

+0

Estoy usando 11.04, y acabo de escribir un script que recorre las imágenes en una carpeta, y utilicé este fragmento. Funcionó bien para mí Sin embargo, estoy ejecutando el comando con os.system (comando) – MikeVaughan

2

En Windows, necesitará algunos trucos con pywin32 y the windows API, en 'linux' la respuesta dependerá de qué escritorio esté funcionando: KDE, Gnome o algo más exótico. Debajo de KDE (y tal vez de Gnome) probablemente pueda enviar un mensaje usando D-Bus, lo cual podría hacer sin incluir ninguna biblioteca nueva usando la herramienta de línea de comando dbus-send.

La otra opción sería la de establecer el fondo de pantalla a un archivo que luego editar/cambiar de pitón - pero esto probablemente sólo resultará en un cambio cuando el usuario inicia sesión en

32

En Windows con python2.. 5 o superior, use ctypes para cargar user32.dll y llame al SystemParametersInfo() con la acción SPI_SETDESKWALLPAPER.

Por ejemplo:

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

+1 ctypes es preferible a pywin32 – James

+2

Parece que no funciona con .jpg, funciona con .bmp tho (en xp) – Noelkd

+2

Utilicé con éxito un jpg en win 7 – CrazyPenguin

6

en GNOME, es probable que sea preferible utilizar el pitón unión de gconf directamente:

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

En primer lugar, la importación ctypes: se le da acceso a los componentes de Windows, como el protector de pantalla, fondos de pantalla, etc. .

A continuación, llame ctypes.windll.user32.SystemParametersInfoA(a,b,c,d):

a = 20

b = 0

c = la ruta completa de la imagen. Not just the path from the active directory

d = 0

9

uso el método siguiente en uno de mis proyectos iniciales:

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

El método get_desktop_environment ha sido publicado in another thread.

+1

En lugar de la función 'get_home_dir()', puede usar 'os.path.expanduser ('~')' –

1

cambiar la imagen de fondo de escritorio

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

funcionó bien para mí. windows10, python27

2

Existe una diferencia de cómo se llama el método SystemParametersInfo en función de qué ocurre si se está ejecutando en sistemas operativos de 64 bits o 32 bits. Para 64 bits tiene que usar SystemParametersInfoW (Unicode) y para 32 bits 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

Esto no tiene sentido. La elección de ASCII o Unicode no tiene ninguna relación con si está ejecutando Windows de 32 o 64 bits. (Debía usar ASCII en Windows de 16 bits y Windows 95/98/ME, pero Windows NT siempre ha sido compatible con Unicode, versiones de 32 bits y de 64 bits). –

+0

@HarryJohnston, entonces, ¿cómo se explica 'SystemParametersInfoA' no funciona en Windows 10 de 64 bits? – Johnny

+1

@Johnny, acabo de probarlo, y funciona perfectamente bien para mí. Eso es de C, fíjate, entonces todavía es * posible * que haya alguna rareza relacionada con Python que de alguna manera depende de la fragilidad del sistema operativo, aunque eso parece muy poco probable. Mirando la documentación de los tipos, * debería * depender solo de si está usando Python 2 o Python 3. –

6

para Python3.5, SystemParametersInfoA no funciona.Use SystemParametersInfoW.

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

¿Es Python o los tipos de Windows utilizados? – Johnny

+0

Python2 usa ** SystemParametersInfoA ** y Python3 usa ** SystemParametersInfoW ** – mesksr

Cuestiones relacionadas