Как изменить фон рабочего стола на python?

Как изменить фон рабочего стола на python?

Я хочу сделать это как в Windows, так и в Linux.

9 ответов

На рабочем столе 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


В Windows с python2.5 или выше используйте ctypes для загрузки user32.dll и вызывайте SystemParametersInfo() с действием SPI_SETDESKWALLPAPER.

Например:

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


Я использую следующий метод в одном из моих первоначальных проектов:

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<
<p>Метод get_desktop_environment опубликован <a href="https://qa-help.ru/questions/kakova-moya-tekushhaya-sreda-rabochego-stola" target="_blank">в другом потоке</a>.</p>


В gnome, вероятно, предпочтительнее использовать прямое связывание gconf с python:

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


Для Python3.5 SystemParametersInfoA не работает. Использовать SystemParametersInfoW.

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


В окнах вам понадобятся некоторые трюки с pywin32 и API Windows, на 'linux' ответ будет зависеть от того, какой рабочий стол запущен - KDE, Gnome или что-то более экзотическое. В KDE (и, возможно, Gnome) вы, вероятно, можете отправить сообщение с помощью D-Bus, которое вы могли бы сделать без включения каких-либо новых библиотек с помощью инструмента командной строки dbus-send.

Другой вариант - установить обои рабочего стола в файл, который вы затем отредактируете/замените на python, но это, вероятно, приведет только к изменению при входе пользователя в систему.


Во-первых, import ctypes: он дает вам доступ к компонентам Windows, таким как заставка, обои и т.д.

Затем вызовите ctypes.windll.user32.SystemParametersInfoA(a,b,c,d):

a= 20

b= 0

c= Путь COMPLETE изображения. Не только путь из активного каталога

d= 0


Есть разница в том, какой метод SystemParametersInfo вызывается на основе того, что если вы работаете на 64-битной или 32-разрядной ОС. Для 64 бит вы должны использовать SystemParametersInfoW (Unicode) и для 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()


изменение фонового изображения рабочего стола

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

licensed under cc by-sa 3.0 with attribution.