原文链接网址mp.weixin.qq.com看效果展示:https://zhuanlan.zhihu.com/p/...前段时间介绍一个小伙伴离开了留言说要我带你写个小桌面挂件。今天就满足下类似留言的小伙伴的要求吧~不过感觉写桌面日历很无聊,所以索性带大家做一个桌面宠物。废话不多说,开开心心开始~开发工具Python版本:3.6.4相关模块:PyQt5模块;以及Python自带的一些模块。原理介绍既然要写桌面宠物,首先当然要找到宠物的图片素材。这里我们使用的是shimiji手机APP的宠物图片素材,比如皮卡丘:我下载了大概60种宠物图片素材供大家选择:都在相关文件中打包提供了,就不分享了他们这里的爬虫代码(我选的,只要不是觉得特别难看,我基本都保留),不要给别人的服务器带来不必要的压力。接下来,我们可以开始设计我们的桌面宠物。鉴于网上用python写的桌面小部件基本都是基于tkinter的,为了突出公众号的不同,这里使用PyQt5来实现我们的桌面宠物。首先我们初始化一个桌面宠物窗口组件:像这样:接下来,我们设置窗口的属性,使它更适合宠物窗口:setAttribute(Qt.WA_TranslucentBackground,True)self.repaint()并随机导入一张宠物图片,看运行效果:#随机导入一张宠物self.pet_images,iconpath=self.randomLoadPetImages()#当前显示的图片self.image=QLabel(self)self.setImage(self.pet_images[0][0])随机导入宠物所有图片的函数代码实现如下:'''随机导入桌面宠物所有图片'''defrandomLoadPetImages(self):pet_name=random.choice(list(cfg.PET_ACTIONS_MAP.keys()))actions=cfg.PET_ACTIONS_MAP[pet_name]pet_images=[]foractioninactions:pet_images.append([self.loadImage(os.path.join(cfg.ROOT_DIR,pet_name,'shime'+item+'.png'))foriteminaction])iconpath=os.path.join(cfg.ROOT_DIR,pet_name,'shime1.png')returnpet_images,iconpath当然我们也希望宠物每次在桌面上的位置都是随机的,这样会比较有趣:'''随机到屏幕上的某个位置'''defrandomPosition(self):screen_geo=QDesktopWidget().screenGeometry()pet_geo=self.geometry()width=(screen_geo.width()-pet_geo.width())*random.random()height=(screen_geo.height()-pet_geo.height())*random.random()self.move(width,height)现在运行我们的程序,效果是这样的:好像还不错~等等,好像有问题。重置窗口属性后,这个东西干嘛退出来?宠物右上角加个×之类的符号好像很奇怪?别着急,我们可以给我们的桌面宠物添加一个托盘图标来实现桌面宠物程序的退出功能:#设置退出选项quit_action=QAction('quit',self,triggered=self.quit)quit_action.setIcon(QIcon(iconpath))self.tray_icon_menu=QMenu(self)self.tray_icon_menu.addAction(quit_action)self.tray_icon=QSystemTrayIcon(self)self.tray_icon.setIcon(QIcon(iconpath))self.tray_icon.setContextMenu(self.tray_icon_menu)自己。tray_icon.show()的效果是这样的:OK,好像造型不错~但是还是不太对,每次桌面随机生成宠物的位置,但是我们做不到调整这个宠物的位置明显不合理。作为桌面宠物,一定不能处于妨碍主人工作的位置!我们写下鼠标按下、移动、松开时的函数,让它可以用鼠标拖动:'''当按下鼠标左键时,宠物会被绑定到鼠标位置'''def鼠标前ssEvent(self,event):如果event.button()==Qt.LeftButton:self.is_follow_mouse=Trueself.mouse_drag_pos=event.globalPos()-self.pos()event.accept()self.setCursor(QCursor(Qt.OpenHandCursor))'''当鼠标移动时,宠物也跟着移动'''defmouseMoveEvent(self,event):ifQt.LeftButtonandself.is_follow_mouse:self.move(event.globalPos()-self.mouse_drag_pos)event.accept()'''鼠标松开时解除绑定'''defmouseReleaseEvent(self,event):self.is_follow_mouse=Falseself.setCursor(QCursor(Qt.ArrowCursor))效果如下:哈哈,越来越体面了~终于结束了,作为一只活泼的宠物,总不能这么死板,一动也不动吧?反正总要学会做表情才能逗主人开心吧?OK,我们先设置一个定时器:#Makeanactioneveryonceinawhileself.timer=QTimer()self.timer.timeout.connect(self.randomAct)self.timer.start(500)timereveryonceinawhileTimetoswitchthepictureoftheselectedpettoachievetheanimationofpet'sfacialexpressions(视频的基本内容都是一帧一帧的图片组成的,不用我科普一下T_T)当然,这里我们必须编辑图片动作分类(执行相同动作的图片属于同一类别)以保证宠物面部表情的连贯性。具体代码实现如下:'''随机做一个动作'''defrandomAct(self):ifnotself.is_running_action:self.is_running_action=Trueself.action_images=random.choice(self.pet_images)self.action_max_len=len(self.action_images)self.action_pointer=0self.runFrame()'''完成动作的每一帧'''defrunFrame(self):ifself.action_pointer==self.action_max_len:self.is_running_action=Falseself.action_pointer=0self.action_max_len=0self.setImage(self.action_images[self.action_pointer])self.action_pointer+=1OK,大功告成~完整源码见相关文件。相关文档见:https://github.com/CharlesPikac
