写一个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 ...
随机推荐
- IK分词器实现原理剖析 —— 一个小问题引发的思考
前言: 网上很多的文章都建议在使用IK分词器的时候,建立索引的时候使用ik_max_word模式:搜索的时候使用ik_smart模式.理由是max_word模式分词的结果会包含smart分词的结果,这 ...
- 监控Redis集群--废弃,使用新教程
prometheus监控redis需要用到redis_exporter. redis_exporter 项目地址:https://github.com/oliver006/redis_exporter ...
- Java开发学习(三十六)----SpringBoot三种配置文件解析
一. 配置文件格式 我们现在启动服务器默认的端口号是 8080,访问路径可以书写为 http://localhost:8080/books/1 在线上环境我们还是希望将端口号改为 80,这样在访问的时 ...
- 220726 T2 Multisets (思维)
题目描述 我们说一个可重集 AA 比可重集 BB 小,当且仅当对于两个可重集中出现次数不同的最小元素 xx ,元素 xx 在 AA 中出现次数更多. 例如,可重集 {1,2,3}1,2,3 就比可重集 ...
- 洛谷P1908 逆序对 (树状数组+离散化)
模板题,树状数组加上离散化求逆序对. 1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 ...
- 几个Caller-特性的妙用
System.Runtime.CompilerServices命名空间下有4个以"Caller"为前缀命名的Attribute,我们可以将它标注到方法参数上自动获取当前调用上下文的 ...
- Idea运行支付宝网站支付demo踩坑解决及其测试注意事项
一.前言 在一些商城网上中,必不可少的是支付,支付宝和微信比较常见,最近小编也是在研究这一块,看看支付宝怎么进行支付的,支付宝给我们提供了demo和沙箱测试.减少我们的申请的麻烦,公钥和秘钥也比之前方 ...
- linux 自动备份mysql数据库
今天一早打开服务器.13W个木马.被爆破成功2次,漏洞3个.数据库被删.这是个悲伤的经历 还好之前有备份,服务器也升级了安全机制,只是备份是上个月的备份.所以想写个脚本,试试自动备份数据库. 1. 先 ...
- 齐博X1忘记管理员密码了怎么办?如何强制进后台?
当你忘记密码,或者是某些原因导致进不了后台的话,这个时候你修改一下根目录的admin.php文件,把文件第二行 //define('SUPER_ADMIN',true); 前面的 // 双斜杠删除,再 ...
- 微服务组件--注册中心Spring Cloud Eureka分析
Eureka核心功能点 [1]服务注册(register):Eureka Client会通过发送REST请求的方式向Eureka Server注册自己的服务,提供自身的元数据,比如ip地址.端口.运行 ...