¿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.
¿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.
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
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
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
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
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 ctypes es preferible a pywin32 – James
Parece que no funciona con .jpg, funciona con .bmp tho (en xp) – Noelkd
Utilicé con éxito un jpg en win 7 – CrazyPenguin
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')
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
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.
En lugar de la función 'get_home_dir()', puede usar 'os.path.expanduser ('~')' –
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
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()
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). –
@HarryJohnston, entonces, ¿cómo se explica 'SystemParametersInfoA' no funciona en Windows 10 de 64 bits? – Johnny
@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. –
para Python3.5, SystemParametersInfoA no funciona.Use SystemParametersInfoW.
import ctypes
ctypes.windll.user32.SystemParametersInfoW(20, 0, "absolute path" , 0)
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
¿Alguien sabe cómo hacer esto en KDE? – TheInitializer