Come posso cambiare lo sfondo del mio desktop con python?Come posso cambiare lo sfondo del mio desktop con python?
Voglio farlo sia in Windows che in Linux.
Come posso cambiare lo sfondo del mio desktop con python?Come posso cambiare lo sfondo del mio desktop con python?
Voglio farlo sia in Windows che in Linux.
Su un desktop GNOME, di solito si esegue questa operazione con gconf, sia chiamando direttamente gconftool o utilizzando il modulo gconf pitone. Quest'ultimo è nel link dato da unutbu. Il primo metodo potrebbe essere fatto in questo modo.
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
Per Ubuntu 11.04 questo non sembra funzionare. L'impostazione gconf cambia, ma lo sfondo non si aggiorna alla nuova immagine. – hobs
Sto usando 11.04 e ho appena scritto uno script che scorre le immagini in una cartella, e ho usato questo frammento. Ha funzionato bene per me. Tuttavia, sto eseguendo il comando con os.system (comando) – MikeVaughan
Su Windows, avrete bisogno di qualche trucco con pywin32 e the windows API, su 'linux' la risposta dipenderà da quale desktop è in esecuzione - KDE, Gnome, o qualcosa di più esotico. Sotto KDE (e forse Gnome) puoi probabilmente inviare un messaggio usando D-Bus, che potresti fare senza includere nuove librerie usando lo strumento da riga di comando dbus-send.
L'altra opzione sarebbe quella di impostare lo sfondo del desktop in un file che poi modificare/sostituire in pitone - ma questo probabilmente comporterà solo un cambiamento quando l'utente accede a
su Windows con python2.. 5 o versione successiva, utilizzare i tipi di codice per caricare user32.dll e chiamare SystemParametersInfo()
con l'azione SPI_SETDESKWALLPAPER.
Ad esempio:
import ctypes
SPI_SETDESKWALLPAPER = 20
ctypes.windll.user32.SystemParametersInfoA(SPI_SETDESKWALLPAPER, 0, "image.jpg" , 0)
+1 ctypes è preferibile a pywin32 – James
Non sembra funzionare con un .jpg, funziona con un .bmp tho (su xp) – Noelkd
Ho usato con successo un jpg su win 7 – CrazyPenguin
in GNOME, è probabilmente preferibile utilizzare il pitone legame di gconf direttamente:
import gconf
conf = gconf.client_get_default()
conf.set_string('/desktop/gnome/background/picture_filename','/path/to/filename.jpg')
In primo luogo, l'importazione ctypes
: esso consente di accedere ai componenti di Windows, come lo screensaver, sfondi, ecc .
Quindi chiamare ctypes.windll.user32.SystemParametersInfoA(a,b,c,d)
:
a
= 20
b
= 0
c
= Il percorso completo dell'immagine. Not just the path from the active directory
d
= 0
Io uso il seguente metodo in uno dei miei primi progetti:
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.")
Il metodo get_desktop_environment è stata pubblicata in another thread.
Invece della funzione 'get_home_dir()', puoi semplicemente usare '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'
sfondo ha funzionato bene per me. windows10, python27
C'è una differenza tra il metodo SystemParametersInfo da chiamare in base a ciò che accade se si utilizza il sistema operativo a 64 bit o 32 bit. Per 64 bit è necessario utilizzare SystemParametersInfoW (Unicode) e per il 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()
Questo non ha senso. La scelta di ASCII o Unicode è completamente indipendente dal fatto che si stiano utilizzando Windows a 32 o 64 bit. (Dovevi usare ASCII su Windows a 16 bit e Windows 95/98/ME, ma Windows NT ha sempre supportato Unicode, entrambe le versioni a 32 e 64 bit.) –
@HarryJohnston come spieghi 'SystemParametersInfoA' non funziona su Windows 10 a 64 bit? – Johnny
@Johnny, l'ho appena provato e funziona perfettamente per me. Quello è da C, bada bene, quindi è ancora * possibile * che ci sia qualche stranezza legata a Python che in qualche modo dipende dal buon senso del sistema operativo, anche se sembra molto improbabile. Osservando la documentazione dei ctypes, * dovrebbe * dipendere solo dal fatto che tu stia usando Python 2 o Python 3. –
Per Python3.5, SystemParametersInfoA non funziona.Usa SystemParametersInfoW.
import ctypes
ctypes.windll.user32.SystemParametersInfoW(20, 0, "absolute path" , 0)
per il Linux-metà della tua domanda, (e assumendo un ambiente desktop GNOME), si potrebbe voler dare un'occhiata a http://oracle.bridgewayconsulting.com.au/~danni/misc/ change-background-py.html – unutbu
Qualcuno sa come farlo in KDE? – TheInitializer