python桌面壁纸键盘鼠标交互

1.灵感来源

        最近想起来之前看见过的一个桌面宠物,会在屏幕的一小部分区域显示一只猫,当用户点击键盘和鼠标的时候,那只猫也会有相应的动作。百般搜索找到那个桌宠软件的名字叫Bongo Cat Mver。回想这个软件的时候,我把BongoCat当成了桌面壁纸软件(然而并不是),既然记错了,那就将错就错吧,做一个可以和用户键盘鼠标交互的桌面壁纸。

2.设计思路

       首先选择使用Python开发,之后的实现思路就是监听用户键盘输入,监听用户鼠标点击,在触发相应的事件后修改桌面壁纸,关于桌面壁纸的图片来自于Bongo Cat Mver软件的截屏。

3.准备壁纸

    壁纸图片是由Bongo Cat Mver软件运行后通过截屏所得。在用户键盘按下“q,w,e,r,a,s,d,1,2,3,4,5,6,7”按键、鼠标左右键和猫咪待机时,对那只猫的动作进行截屏,总共18张图片,保存到img文件夹。相同的截图动作要重复18次,就想到了用代码来完成截图保存操作,每个图片的名称都由相应的KeyCode来命名,如a.jpg。

import sys
import ctypes
import os
from pynput.keyboard import Key, Listener
import getpass
import shutil
from PIL import ImageGrab

key_list = ['1','2','3','4','5','6','7',
            'a','d','e','q','r','w','s', 'Key.space']
#监听用户键盘输入,有输入时进行全屏截图
def on_press(key):
    key_char = str(key).replace('\'','')
    if key_char in key_list:
        if key_char.isalpha():
            key_char = key_char.lower()
        
        file_path = 'img/' + key_char + '.jpg'
        abs_path = os.path.abspath(file_path)
        #这里进行全屏截图
        pic = ImageGrab.grab()
        #指定保存图片的位置,可以是当前.py文件的相对路径
        pic.save(abs_path)

    #当点击9时进行猫咪待机截屏
    if key_char not in key_list and key_char == '9':
        file_path = 'img/start.jpg'
        abs_path = os.path.abspath(file_path)
        print(abs_path)
        pic = ImageGrab.grab()
        pic.save(abs_path)
    #为了偷懒,懒得加上鼠标监听,这里当用户按住鼠标右键,再点击数字8时,进行猫咪点击鼠标右键的动作截屏
    if key_char not in key_list and key_char == '8':
        file_path = 'img/right.jpg'
        abs_path = os.path.abspath(file_path)
        print(abs_path)
        pic = ImageGrab.grab()
        pic.save(abs_path)
    #为了偷懒,懒得加上鼠标监听,这里当用户按住鼠标左键,再点击数字0时,进行猫咪点击鼠标左键的动作截屏
    if key_char not in key_list and key_char == '0':
        file_path = 'img/left.jpg'
        abs_path = os.path.abspath(file_path)
        print(abs_path)
        pic = ImageGrab.grab()
        pic.save(abs_path)

def on_release(key):
    #直接返回True代表不做处理,如果返回False,则无法继续监听用户键盘输入
    return True

if __name__ == '__main__':
    #定义用户键盘监听器
    with Listener(on_press = on_press, on_release=on_release) as listener:
        #开始监听
        listener.join()

        关于为什么键盘按键只收集“q,w,e,r,a,s,d,1,2,3,4,5,6,7”,是因为Bongo Cat Mver的鼠标键盘模式只响应这些按键,而我又不会画图......。如果有想法,大家可以画出猫咪点击其他按键的图片。        

        在运行截图程序前要确定Bongo Cat Mver正常运行,另外点击每个按键的时间不能太短,因为程序截图需要时间执行,如果点击过快,截图只能截到猫咪抬手的图片。

        在获得18张全屏图片后,需要裁剪出图片中的猫咪部分,如下图

        如果手动截图的话,每张图片的裁剪边界容易产生误差,并且很麻烦,所以这里也是使用了代码来帮助我们裁剪图片(代码真好用),从img文件夹获取全屏截图文件,裁剪后保存到format文件夹中,查看裁剪图片正常后将文件夹改名为resources文件夹(个人习惯,可以不改)。

from PIL import Image
import os

#获取img文件夹的全部截图文件
for root, dirs, files in os.walk('img'):
    #循环遍历每一个截图文件
    for file in files:
        #如果是以.jpg结尾的文件,就进行裁剪
        if os.path.splitext(file)[-1] == '.jpg':
            img = Image.open("./img/"+file)
            #img.crop()参数需要一个长度为4的元组,代表裁剪的左,上,右,下四个坐标
            cropped = img.crop((400, 180, 2520, 1400))
            #将截取的文件保存到format文件夹
            cropped.save("./format/"+file)

 4.监听用户键盘,鼠标输入

        准备好图片后,要在恰当的时机显示恰当的壁纸,恰当的时机指的就是用户键盘和鼠标输入的时机,所以我们需要用Python监听键盘和鼠标的输入,这里使用的是Python的pynput模块。

from pynput.keyboard import Key, Listener
import pynput

if __name__ == '__main__':
    #将猫咪的待机动作设置成初始壁纸
    start_file = 'resources/start.jpg'
    abs_path = os.path.abspath(start_file)
    ctypes.windll.user32.SystemParametersInfoW(20, 0, abs_path, 0)  # 设置桌面壁纸
    #添加鼠标监听器
    mlistener = pynput.mouse.Listener(on_click=on_click)
    mlistener.start()
    #添加键盘监听器
    with Listener(on_press = on_press, on_release=on_release) as listener:
        listener.join()

        关于同时监听键盘和鼠标,不能同时使用两个with语句,因为监听器的join()方法会阻塞程序,这样就只有第一个设置的监听器会起作用,所以鼠标监听器使用的是start()非阻塞方法。

        然后自定义on_click(鼠标点击),on_press(键盘按下), on_release(键盘释放)动作发生时的壁纸响应动作。

#鼠标点击时调用该方法
def on_click(x,y,button,pressed):
    #pressed为True代表用户手指按下鼠标,为False代表用户手指抬起
    if pressed:
        #获取鼠标按键的名称,用以区分单机左键还是右键
        buttonName = str(button)
        if buttonName == "Button.left":
            file_path = 'resources/left.jpg'
        elif buttonName == "Button.right":
            file_path = 'resources/right.jpg'
        abs_path = os.path.abspath(file_path)
        ctypes.windll.user32.SystemParametersInfoW(20, 0, abs_path, 0)  # 设置桌面壁纸
    else:
        #当用户手指抬起,壁纸恢复为猫咪的待机动作
        start_file = 'resources/start.jpg'
        abs_path = os.path.abspath(start_file)
        ctypes.windll.user32.SystemParametersInfoW(20, 0, abs_path, 0)  # 设置桌面壁纸

#键盘按下时调用该方法
def on_press(key):
    key_char = str(key).replace('\'','')
    if key_char in key_list:
        if key_char.isalpha():
            #防止用户锁定大写,resources文件夹找不到相应图片,转为小写
            key_char = key_char.lower()

        #这里通过KeyCode拼接图片路径,也就是为什么图片名称要以KeyCode命名的原因
        file_path = 'resources/' + key_char + '.jpg'
        abs_path = os.path.abspath(file_path)
        ctypes.windll.user32.SystemParametersInfoW(20, 0, abs_path, 0)  # 设置桌面壁纸

#键盘按键松开调用该方法
def on_release(key):
    #当键盘按键释放,壁纸恢复为猫咪的待机动作
    start_file = 'resources/start.jpg'
    abs_path = os.path.abspath(start_file)
    ctypes.windll.user32.SystemParametersInfoW(20, 0, abs_path, 0)  # 设置桌面壁纸

        最核心的一句设置桌面壁纸的代码是

ctypes.windll.user32.SystemParametersInfoW(20, 0, abs_path, 0)

        第一个参数20就代表设置系统的壁纸参数,第三个参数指的是壁纸的绝对路径,这里不能使用相对路径,不然壁纸会被设置为纯黑色。

5.丰富一点细节

        在程序启动时,将原本的壁纸保存到resources文件夹,毕竟Bongo Cat Mver放大后能看见像素点(如果有画画高手可以替换Bongo Cat Mver的资源图片为高清的),关闭程序后可以找到原来的壁纸文件。

import getpass
import os

def Get_Background_Path():
    old_name = "C:/Users/" + getpass.getuser() + "/AppData/Roaming/Microsoft/Windows/Themes/CachedFiles"
    old_name = old_name + "/" + os.listdir(old_name)[0]
    resources_path = os.path.abspath('resources')
    new_name = resources_path + "/back.jpg"
    shutil.copyfile(old_name, new_name)

6.代码目录

 7.运行效果

python桌面壁纸键盘鼠标交互

虽然壁纸的像素并不高,但是已经有了实现思路,只要有高清的图片,就可以替换资源。

猜你喜欢

转载自blog.csdn.net/qq_43536827/article/details/123641628