python桌面壁纸键盘鼠标交互

news/2024/11/9 2:42:20/

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 ImageGrabkey_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 Trueif __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 pynputif __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 osdef 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桌面壁纸键盘鼠标交互

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


http://www.ppmy.cn/news/128472.html

相关文章

Python 模拟键盘鼠标操作实战教程

在某些情况下,如果我们需要进行自动化操作的应用没有提供相应的接口,我们无法直接通过Python来调用API实现自动化。这种情况下,Python也不是完全没有办法的,我们可以采用模拟键盘和鼠标的方式实现自动化。 Python中模拟键盘和鼠标…

所有键盘鼠标模拟方式原理及实现

前言: 有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的要求比较高,比如赛车游戏,要求以最快速度响应键盘输入。而windows消息由于是…

Ubuntu 键盘鼠标失效解决办法

问题描述:启动Ubuntu键盘鼠标失效/失灵,只能通过电源键重启,重启仍解决不了问题。 今天打开Ubuntu,键盘鼠标失灵了!!!查找国内博客解决方案发现都无法解决(气…,秉着不成功便成仁的信…

超越象限:解密 α 碎片的归属问题

文章目录 参考环境α 碎片的归属问题问题概述终边相同角圆心角终边相同角 象限角 描述象限角第一象限角任意象限角 特殊方案问解 叠加坐标系上部下部叠加坐标系 一般方案问解任意角 α分析绘图要领叠加坐标系N-N 参考 项目描述搜索引擎Google 、Bing百度百科首页佟大大还是ETT…

退格键消除-栈

退格键消除问题-栈 题目描述 输入一个字符串只包含$和小写英文字母的字符串s,如ab$$cd,每遇到一个字符$,就删除其前面的字符(如果有的话);最后输出的字符串中不包含$字符,求最后返回剩余的小写…

Maui中基本控件目录

基本控件介绍 控件名中文名称说明Button按钮与WPF中的基础用法无太大变化CheckBox单选框与WPF中的基础用法无太大变化ListView列表类似WPF中列表控件“ListBox”ImageButton图片按钮WPF中没有该控件,通常需要开发者手动实现,MAUI中已经包含在基础控件中。…

SQL server 字段内容多出空白字符

SQL server 字段内容多出空白字符 字段格式问题,将字段改为可变长类型 nvarchar varchar 类型

最贵电视来袭

还记得前不久,国民老公王思聪花50W买了台岛国的百吋电视,安装时把自家强都砸了,才用吊机吊入室内安放的。 AWE展上又展出了一款“棒子国”的最新百吋电视机,Samsung qled系列电视机,其中的百吋款售价直接达到了100W&am…