用python更换桌面壁纸

windows自带幻灯片壁纸功能,但我发现它有时会导致一个叫"Shell Infrastructure Host"的进程占用大量CPU资源。为了平衡一个阿宅对CPU和二次元的需求,敲点代码代替它。

功能:选择文件夹,定时随机切换壁纸。可以通过托盘图标修改参数或即时切换。

原理是很简单的,只用到一个api,只不过为了方便和美观做了些改进。

用到的第三方库有 easygui, pystray, APScheduler和configparser, 分别是用来提供对话框、托盘图标(算作提供一个操作入口,不过像windows那样在桌面右键菜单里加选项似乎更方便一点)、定时任务调度和参数解析。

不想打包的话可以把py文件后缀改成pyw,这样就没有控制台窗口了。

from easygui import diropenbox,integerbox,boolbox # 简单对话框
from random import randint # 随机数
from os import listdir # 读取文件名
from os.path import join # 合并路径
from PIL.Image import open as openImage # 读取图片
from pystray import MenuItem,Icon # 托盘图标
from ctypes import windll # 设置壁纸的api
from apscheduler.schedulers.background import BackgroundScheduler # 定时任务
from datetime import datetime # 提供now()函数以即时触发任务
from configparser import ConfigParser # 读取参数

class WallpaperChanger:
    def __init__(self):
        self.initConfig() # 初始化参数
        self.setScheduler() # 设置调度器
        self.setIcon() # 设置托盘

    def initConfig(self):
        self.index = 0
        try:
            self.readConfig()
        except:
            self.config = None
            self.path = ''
            self.timeSep = 360
            self.random = False
            self.setConfig(setRandom=False) 
            # 为了方便,默认不开启随机

    def readConfig(self):
        # 读取参数
        print('读取参数...')

        self.config = ConfigParser()
        self.config.read('config.ini')

        self.path = self.config['DEFAULT']['path']
        print('图片路径: %s' % self.path)

        self.timeSep = self.config['DEFAULT'].getint('timeSep')
        print('时间间隔: %s' % self.displayMinute(self.timeSep))

        self.random = self.config['DEFAULT'].getboolean('random')
        print('随机: %s' % self.random)

    def setConfig(self,setPath=True,setTimeSep=True,setRandom=True):
        # 更改参数
        if setPath:
            path = ''
            while not path:
                path = diropenbox(msg='选择壁纸所在的文件夹',\
                    default=self.path)
            self.path = self.config['DEFAULT']['path'] = path
            print('图片路径设置为: %s' % path)

        if setTimeSep:
            timeSep = integerbox(msg='切换壁纸的时间间隔(分钟)',\
                title='输入时间间隔',default=self.timeSep,lowerbound=1,upperbound=43200)
                # 默认6个小时换一次。设置下限和上限。
            if timeSep:
                self.timeSep = timeSep
                self.config['DEFAULT']['timeSep'] = str(self.timeSep)
                print('时间间隔设置为: %s' % self.displayMinute(self.timeSep))

        if setRandom:
            self.random = not self.random
            # 通过勾选菜单来更改随机选择,只需要每次更改时取反即可
            self.config['DEFAULT']['random'] = str(self.random)
            print('随机设置为: %s' % self.random)
        
        with open('config.ini','w') as file:
            self.config.write(file)

    def setWallpaper(self):
        # 更改墙纸
        imgs = list(map(lambda img:join(self.path,img),listdir(self.path)))
        if self.random:
            self.index = randint(0,len(imgs)-1)
        else:
            self.index = (self.index+1) % len(imgs)
            # 取模运算实现数列循环
        img = imgs[self.index]
        windll.user32.SystemParametersInfoW(20,0,img,0)
        # 我没搞清这几个参数的作用
        print('壁纸已更改为:%s' % img)
    
    def displayMinute(self,minutes):
        # 由minutes选择合适的时间单位
        days=minutes//1440
        minutes=minutes%1440
        hours=minutes//60
        minutes=minutes%60

        output=''
        if days:
            output += '%d天' % days
        if hours:
            output += '%d小时' % hours
        if minutes:
            output += '%d分钟' % minutes

        return output

    def setScheduler(self):
        # 设置调度器
        self.scheduler = BackgroundScheduler(timezone='Asia/Shanghai')
        self.job = self.scheduler.add_job(func=self.setWallpaper,trigger='interval',minutes=self.timeSep)

    def setIcon(self):
        # 设置托盘
        def next():
            self.job.modify(next_run_time=datetime.now())

        def random():
            self.setConfig(False,False,True)

        def timeSep():
            self.setConfig(False,True,False)
            self.timeSepMenu = MenuItem('时间间隔: %s' % self.displayMinute(self.timeSep),timeSep)
            self.icon.menu = (self.nextMenu,self.randomMenu,self.timeSepMenu,self.pathMenu,self.exitMenu)
            # 更新菜单文本
            self.job.reschedule(trigger='interval',minutes=self.timeSep)
            # 更新任务

        def path():
            self.setConfig(True,False,False)
        
        def exit():
            if boolbox('确定退出吗?',choices=('是','否'),default_choice='否',cancel_choice='否'):
                self.stop()

        self.nextMenu = MenuItem('下一张',next)
        self.randomMenu = MenuItem('随机',random,checked=lambda item:self.random)
        self.timeSepMenu = MenuItem('时间间隔: %s' % self.displayMinute(self.timeSep),timeSep)
        self.pathMenu = MenuItem('文件路径',path)
        self.exitMenu = MenuItem('退出',exit)

        menu = (self.nextMenu,self.randomMenu,self.timeSepMenu,self.pathMenu,self.exitMenu)

        self.icon = Icon('',openImage('icon.ico'),'wallpaper changer',menu)

    def run(self):
        self.scheduler.start()
        self.icon.run()
    
    def stop(self):
        self.scheduler.shutdown()
        self.icon.stop()

if __name__ == '__main__':
    wallpaperChanger = WallpaperChanger()
    wallpaperChanger.run()

代码中用到的 config.ini 文件内容如下。实际上不要这个东西也行…… 另外还需要一张图片 icon.ico 作为托盘图标。

[DEFAULT]
path = D:\Pictures\Desktop
timesep = 60
random = True

效果如图。
在这里插入图片描述
在这里插入图片描述
(我坦白了,我就是为了晒一下我的桌面才写了这个程序发这篇文章。)

github 地址 https://github.com/Luessiaw/WallpaperChanger

  • 5
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值