写一个linux平台的桌面宠物
效果图


前言
我一直在用python 写一下有趣的东西,让编程不那么无聊,之前一直有写一个桌面宠物的想法,无奈这些都是依赖资源文件,没有图片资源没办法写里面的逻辑,直到我看见了 shimiji手机桌面宠物软件


这个软件提供了很多宠物的图片资源,这样就简单了,用 charles 对手机简单抓包,抓取到这些资源链接
http://pepeswap.com/mascot/78
另外示例图片链接
http://pepeswap.com/thumb/78
这里是78,其实号码从 3 到90 都是有资源的,就是没有1,2(1,2是软件内置的)
所以这里一共有 90-3+1=88个资源,这下子图片资源就解决了
然后编写代码
代码
先写一个管理这些资源的软件
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import requests
import threading
import os
import zipfile
from PIL import Image
class Workchange(QThread):
"""docstring for WorkThread"""
change_done = pyqtSignal()
def __init__(self):
super(Workchange, self).__init__()
def run(self):
url = self.url
name = url.split('/')[-1] + '.zip'
print('正在下载资源',name)
data = requests.get(url).content
with open(name,'wb') as f:
f.write(data)
print('下载完成!')
path = os.environ['HOME']+'/shimeji/'
if not os.path.exists(path):
os.makedirs(path)
print('正在解压资源...')
z = zipfile.ZipFile(name, 'r')
z.extractall(path=path)
z.close()
for i in range(1,47):
os.rename(path + 'shime%s.png'% str(i),path+str(i)+'.png')
pri_image = Image.open(path+'%s.png' %str(i))
pri_image.transpose(Image.FLIP_LEFT_RIGHT).save(path+'-%s.png'%str(i))
for i in os.listdir(path):
os.system('convert %s %s'%(path+i,path+i))
print('解压完成')
os.remove(name)
self.change_done.emit()
class Workinit(QThread):
"""docstring for WorkThread"""
init_done = pyqtSignal(dict)
def __init__(self):
super(Workinit, self).__init__()
def run(self):
for i in range(3,90):
threading.Thread(target=self.load,args=(i,)).start()
def load(self,i):
url = ''' http://pepeswap.com/thumb/%s''' %str(i)
data = requests.get(url).content
name = str(i)
dict_data = dict(data=data,name=name)
self.init_done.emit(dict_data)
class DQListWidget(QListWidget):
def __init__(self):
super(DQListWidget, self).__init__()
self.workinit = Workinit()
self.workchange = Workchange()
self.workchange.change_done.connect(self.change_done)
self.workinit.init_done.connect(self.load_picture)
self.workinit.start()
self.itemDoubleClicked.connect(self.change)
def change_done(self):
QMessageBox.about(self,'提示','更换完成!(*>﹏<*)')
def change(self,item):
self.workchange.url = 'http://pepeswap.com/mascot/' + item.text()
self.workchange.start()
def load_picture(self,dict_data):
item = QListWidgetItem(dict_data['name'])
item.setSizeHint(QSize(10, 128))
self.addItem(item)
pixmap = QPixmap()
label = QLabel()
pixmap.loadFromData(dict_data['data'])
label.setPixmap(pixmap)
self.setItemWidget(item,label)
class Mywin(QWidget):
def __init__(self):
super(Mywin, self).__init__()
list_ = DQListWidget()
layout = QVBoxLayout(self)
layout.addWidget(list_)
self.setLayout(layout)
app = QApplication(sys.argv)
mywin = Mywin() # 实例化一个窗口小部件
mywin.setWindowTitle('Hello world!') # 设置窗口标题
mywin.show() #显示窗口
sys.exit(app.exec())
这个程序双击列表中的条目即可下载并更换对应的宠物图片资源
主程序
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
import time
import random
import os
def random_probability(r):
s = random.randint(1,100)
if r >= s:
return True
else:
return False
class Donghua(QWidget):
def __init__(self):
super(Donghua, self).__init__()
self.desktop = QApplication.desktop()
self.screenRect = self.desktop.screenGeometry()
self.HEIGHT = self.screenRect.height()
self.WIDTH = self.screenRect.width()
self.setWindowFlags(Qt.FramelessWindowHint)
# self.setWindowFlags(Qt.SplashScreen)
self.setAttribute(Qt.WA_TranslucentBackground)
self.timer = QTimer()
self.timer.timeout.connect(self.update)
self.img_timer = QTimer()
self.img_timer.timeout.connect(self.update_img)
self.label = QLabel(self)
self.label.setScaledContents(True)
layout = QVBoxLayout(self)
layout.addWidget(self.label)
self.setLayout(layout)
self.index = 0
self.x = 0
self.is_right = True
self.m_flag = False
self.action_dcit = {
'left_go':(1,3),
'right_go':(-3,-1),
'left_hold':(5,7),
'right_hold':(-7,-5),
'left_release':(4,4),
'right_release':(-4,-4),
'left_down':(18,19),
'right_down':(-19,-18),
'left_crawl':(12,14),
'right_crawl':(-14,-12),
# 'left_rest':(15,17),
# 'right_rest':(-17,-15),
'left_rest':(26,27),
'right_rest':(-27,-26),
'left_rest2':(27,29),
'right_rest2':(-29,-27),
}
self.action = 'right_release'
self.pre_action = ''
# 控制窗体移动及各种动作切换计时器
self.timer.start(100)
# 控制图片切换计时器
self.img_timer.start(200)
#监听鼠标动作
def mousePressEvent(self, event):
x = (event.globalPos()-self.pos()).x()
y = (event.globalPos()-self.pos()).y()
if event.button() == Qt.LeftButton and x < 128 and y < 128:
self.m_flag = True
self.m_Position = event.globalPos()-self.pos() # 获取鼠标相对窗口的位置
event.accept()
if self.is_right:
self.action='right_hold'
else:
self.action='left_hold'
self.setCursor(QCursor(Qt.OpenHandCursor))
def mouseMoveEvent(self, QMouseEvent):
if Qt.LeftButton and self.m_flag:
self.move(QMouseEvent.globalPos()-self.m_Position) # 更改窗口位置
QMouseEvent.accept()
#鼠标左键释放
def mouseReleaseEvent(self, QMouseEvent):
self.m_flag = False
if self.is_right:
self.action = 'right_release'
else:
self.action = 'left_release'
#手动将其放入屏幕边缘
if self.x <= 0 and self.y > 0:
self.action = 'left_crawl'
elif self.x + self.width >= self.WIDTH and self.y > 0:
self.action = 'right_crawl'
self.setCursor(QCursor(Qt.ArrowCursor))
#动作更新
def update(self):
self.width = self.geometry().width()
self.height = self.geometry().height()
self.x = self.geometry().x()
self.y = self.geometry().y()
# print(self.x,self.y)
exec('self.%s()'% self.action)
def right_crawl(self):
if self.y > 0:
self.y -= 10
self.setGeometry(self.x,self.y,100,100)
else:
self.action = 'right_release'
def left_crawl(self):
if self.y > 0:
self.y -= 10
self.setGeometry(self.x,self.y,100,100)
else:
self.action = 'left_release'
def right_down(self):
if self.index+1 == self.action_dcit[self.action][1]:
self.action = 'right_go'
def left_down(self):
if self.index+1 == self.action_dcit[self.action][1]:
self.action = 'left_go'
def right_release(self):
if self.y + self.height > self.HEIGHT:
self.action = 'right_down'
else:
self.action = 'right_release'
self.y += 100
self.setGeometry(self.x,self.y,100,100)
def left_release(self):
if self.y + self.height > self.HEIGHT:
self.action = 'left_down'
else:
self.action = 'left_release'
self.y += 100
self.setGeometry(self.x,self.y,100,100)
def right_go(self):
self.x += 5
self.action = 'right_go'
if self.x + self.width> self.WIDTH:
if random_probability(30):
self.action = 'right_crawl'
else:
self.is_right = False
self.action = 'left_go'
if random_probability(1):
self.action = 'right_rest'
self.setGeometry(self.x,self.y,100,100)
def left_go(self):
self.x -= 5
self.action = 'left_go'
if self.x < 0:
if random_probability(30):
self.action = 'left_crawl'
else:
self.is_right = True
self.action = 'right_go'
if random_probability(1):
self.action = 'left_rest'
self.setGeometry(self.x,self.y,100,100)
def right_rest(self):
if random_probability(1):
self.action = 'right_go'
def left_rest(self):
if random_probability(1):
self.action = 'left_go'
def right_hold(self):
pass
def left_hold(self):
pass
#更新图片
def update_img(self):
start_index,end_index = self.action_dcit[self.action]
if self.pre_action != self.action:
self.index = start_index
self.pre_action = self.action
if self.index == end_index:
self.index = start_index
else:
self.index += 1
q = QPixmap(path +'%s.png' % self.index)
self.label.setPixmap(q)
if __name__ == '__main__':
path = os.environ['HOME']+'/shimeji/'
app = QApplication(sys.argv)
mywin = Donghua()
mywin.show()
sys.exit(app.exec())
写一个linux平台的桌面宠物的更多相关文章
- 如何给LG gram写一个Linux下的驱动?
其实就是实现一下几个Fn键的功能,没有标题吹得那么牛. 不知道为啥,LG gram这本子意外的小众. 就因为这个,装Linux遇到的硬件问题就没法在网上直接搜到解决办法了. Fn + F9 实现阅读模 ...
- 如何成为一个Linux内核开发者
你想知道如何成为一个Linux内核开发者么?或者你的老板告诉你,“去为这个设备写一个Linux驱动.“这篇文档的目的,就是通过描述你需要 经历的过程和提示你如何和社区一起工作,来教给你为达到这些目的所 ...
- Linux i2c子系统(一) _动手写一个i2c设备驱动
i2c总线是一种十分常见的板级总线,本文以linux3.14.0为参考, 讨论Linux中的i2c驱动模型并利用这个模型写一个mpu6050的驱动, 最后在应用层将mpu6050中的原始数据读取出来 ...
- linux设备驱动第三篇:如何写一个简单的字符设备驱动?
在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分配的一些内存 ...
- linux设备驱动第三篇:写一个简单的字符设备驱动
在linux设备驱动第一篇:设备驱动程序简介中简单介绍了字符驱动,本篇简单介绍如何写一个简单的字符设备驱动.本篇借鉴LDD中的源码,实现一个与硬件设备无关的字符设备驱动,仅仅操作从内核中分 ...
- 转:一个跨WINDOWS LINUX平台的线程类
来源:http://blog.csdn.net/dengxu11/article/details/7232681 继Windows下实现一个CThread封装类之后,这里我再实现一个跨WINDOWS ...
- 写一个python脚本监控在linux中的进程
在虚拟机中安装Linux中的CentOS7系统 https://baijiahao.baidu.com/s?id=1597320700700593557&wfr=spider&for= ...
- 写一个小CTF平台
0x00.前言 协会要举办信息安全大赛了,初赛的web+crypto+misc主要由我来出题,注册.比赛的平台也都要由我来写 上周日完成了注册页面的后端(前端由另一个女生写的),前天下午大概完成 ...
- 利用 Linux tap/tun 虚拟设备写一个 ICMP echo 程序
本文首发于我的公众号 Linux云计算网络(id: cloud_dev),专注于干货分享,号内有 10T 书籍和视频资源,后台回复「1024」即可领取,欢迎大家关注,二维码文末可以扫. 前面两篇文章已 ...
- 如何配置一个路径,能够既适合Linux平台,又适合Windows平台,可以从这个路径中读取文件
如何配置一个路径,能够既适合Linux平台,又适合Windows平台,可以从这个路径中读取文件? 目的:就是希望在项目的配置文件中配上一样的路径,不管协作者使用的是什么平台,都能够读到文件. 比如:L ...
随机推荐
- 在Windows 2012 R2上安装vcenter 5.5
在Windows 2012 R2上安装vCenter 5.5做个实验,发现安装的时候卡在Install Directory service了. 重启后,再装也一样. 上网查了一下,说是要装好ADLDS ...
- 使用 Loki 收集 Traefik 日志
转载自:https://mp.weixin.qq.com/s?__biz=MzU4MjQ0MTU4Ng==&mid=2247492264&idx=1&sn=f443c92664 ...
- 记录一个奇葩的问题:k8s集群中master节点上部署一个单节点的nacos,导致master节点状态不在线
情况详细描述; k8s集群,一台master,两台worker 在master节点上部署一个单节点的nacos,导致master节点状态不在线(不论是否修改nacos的默认端口号都会导致master节 ...
- 使用supervisor管理tomcat,nginx等进程详解
1,介绍 官网:http://supervisord.org Supervisor是用Python开发的一套通用的进程管理程序,能将一个普通的命令行进程变为后台daemon,并监控进程状态,异常退出时 ...
- Nexus OSS 3 搭建并配置使用 Docker & Git LFS 仓库
转载自:https://cloud.tencent.com/developer/article/1010590 1.Nexus OSS 3 介绍 我们知道 Nexus 是一个强大的 Maven 仓库管 ...
- 知识图谱实体对齐1:基于平移(translation)的方法
1 导引 在知识图谱领域,最重要的任务之一就是实体对齐 [1](entity alignment, EA).实体对齐旨在从不同的知识图谱中识别出表示同一个现实对象的实体.如下图所示,知识图谱\(\ma ...
- flood_it 方法记录
心路历程 根据题面的描述,我们面临的问题无非是,每次将色块更新成什么颜色.又因为是从左上角开始更新,所以我的有了第一个想法. 将左上角的色块命名为"原色块". 对于每个色块,定义4 ...
- 一文读懂 MySQL 索引
1 索引简介 1.1 什么是 MySQL 的索引 官方定义:索引是帮助 MySQL 高效获取数据的数据结构 从上面定义中我们可以分析出索引本质是一个数据结构,他的作用是帮助我们高效获取数据,在正式介绍 ...
- activeMq不能被主机访问的问题
环境说明 主机:mac 虚拟机:VirtualBox 虚拟系统:Centos6.5 问题:虚拟机启动了 activemq. 也关闭了防火墙,但是在主机访问web界面,http://192.168.1. ...
- Kafka之 API实战
Kafka之 API实战 一.环境准备 1)启动zk和kafka集群,在kafka集群中打开一个消费者 [hadoop1 kafka]$ bin/kafka-console-consumer.sh \ ...