PDA

View Full Version : [Python] Desktop background changer



bobng
10-18-2008, 05:16 PM
Seeing as this has no other place (Unless it goes in web programming, which I doubt) I will post it here.

This python script changes the desktop background at random, from a folder of images. Wait until it loads, then press F9 to cycle through all the backgrounds in the folder, or F8 to choose another random one. F7 closes the program.
Download some nice wallpapers from The deviant art wallpaper section (http://www.deviantart.com/#catpath=customization/wallpaper&order=24), and place it in C:/backgrounds/

It demonstrates three things:
How to hook global windows hotkeys
An introduction to the windows API
How to use glob to find a list of files
Requires:
Python 2.5.2 <- NOT 2.6+! (http://www.python.org/download/)
WIn32 extensions (http://python.net/crew/mhammond/win32/Downloads.html)
Psyco - Not necessary, but improves speed. Remove the import and psyco.full() bit to remove requirement (http://psyco.sourceforge.net/)
Ctypes (May come with python 2.5) (http://python.net/crew/theller/ctypes/)

The code is a bit untidy:

# Random desktop wallpaper chooser, mark 2
# Import the time module, we need this for profiling
import time
print 'Random desktop wallpaper chooser started' # Print the header
a = time.time() # Grab the time
# Import our modules!
import ctypes, win32con, glob, random
from ctypes import wintypes
import psyco
b = time.time() # Grab the new time
print 'Importing modules took %s seconds'%str(round(b-a,4)) # Print the time taken
a = time.time() # Grab the new time
psyco.full() # Compile this mutherf*cker!
b = time.time()
print 'Psyco JIT compiled in %s seconds'%str(round(b-a,6)) # Print the time taken

# Lets make some functions, baby!
a = time.time()
def set_background(path):
print 'Changing background to %s'%path
if not user32.SystemParametersInfoA(win32con.SPI_SETDESKW ALLPAPER,0, ctypes.c_buffer(path), win32con.SPIF_SENDWININICHANGE):
print 'Error changing background to %s'%path

def hotkey_1():
# New random background
# Take the file list and choose a random choice from it
if len(files) > 0: set_background(random.choice(files))
else: print 'No files found in C:/backgrounds'

def hotkey_2():
global counter
# Cycle through backgrounds
# Counter variable is called... counter!
if counter == len(files)-1: counter == 0
try:
set_background(files[counter])
print '[%s/%s]'%(counter+1,len(files))
counter = counter + 1
except:
counter = 0
hotkey_2()

def hotkey_3(): exit()

b = time.time()
print 'Creating functions took %s seconds'%str(round(b-a,6))

# Define our shit homie
a = time.time()
files = glob.glob('C:\\backgrounds\\*.*')
print '%s Files found!'%len(files)
counter = 0
user32 = ctypes.windll.user32
byref = ctypes.byref

HOTKEYS = {
1 : (120,0), # F9 - New random background
2 : (119,0), # F8 - Cycle through background
3 : (118,0) # F7 - Close
}

HOTKEY_ACTIONS = {
1 : hotkey_1,
2 : hotkey_2,
3 : hotkey_3
}
b = time.time()
print 'Creating variables took %s seconds'%str(round(b-a,6))

a = time.time()
failed = False
for id, (vk, modifiers) in HOTKEYS.items ():
if not user32.RegisterHotKey (None, id, modifiers, vk):
print "Unable to register id", id
failed = True
if failed: print 'Not all hotkeys may work'
b = time.time()
print 'Hooking keys took %s seconds'%str(round(b-a,6))

hotkey_1()

try:
msg = wintypes.MSG ()
while user32.GetMessageA (byref (msg), None, 0, 0) != 0:
if msg.message == win32con.WM_HOTKEY:
action_to_take = HOTKEY_ACTIONS.get(msg.wParam)
if action_to_take:
action_to_take()
user32.TranslateMessage (byref (msg))
user32.DispatchMessageA (byref (msg))
finally:
for id in HOTKEYS.keys ():
user32.UnregisterHotKey (None, id)

Dan Cardin
10-18-2008, 06:01 PM
awesome! :)

you should add in so that you can change the way each one looks (i.e. center, stretch, etc) though

bobng
10-20-2008, 02:52 PM
Nah, I don't know the bindings to change that.

Also please note that on my machine (And maybe on others) the background does not 'stick'.
It is supposed to, because win32con.SPIF_SENDWININICHANGE is called, but it doesn't. So it thinks that the background is the default one you have, but displays a different one. So when you reboot your computer, the background will return to whatever it was before.