写一个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 ...
随机推荐
- OpenCV读写视频操作
一.读取视频流 在使用OpenCV读取摄像头,或者处理一些磁盘中保存的视频文件时,通常使用VideoCapture进行读取. std::string video_path("/path/to ...
- .Net 不受 EAR 的约束
NPUlrk :https://github.com/NPUlrk 同学在 dotnet/runtime 仓库提出了一共问题: https://github.com/dotnet/runtime/d ...
- Service概述
为何需要 Service Kubernetes 中 Pod 是随时可以消亡的(节点故障.容器内应用程序错误等原因).如果使用 Deployment 运行您的应用程序,Deployment 将会在 Po ...
- 9. Fluentd部署:日志
Fluentd是用来处理其他系统产生的日志的,它本身也会产生一些运行时日志.Fluentd包含两个日志层:全局日志和插件级日志.每个层次的日志都可以进行单独配置. 日志级别 Fluentd的日志包含6 ...
- 在PE文件中简单注入代码,实现在启动前弹窗
获得的新知识: 1.kernel32.dll,user32.dll,ntdll.dll等一些dll在同一个PC环境下的映射到虚拟内存基址是一样的. 2.在win8以上系统上,更改PE文件的入口点要大于 ...
- liunx之expect操作详解
导航: 一.expect安装.介绍.使用场景二.expect使用原理三.expect使用语法四.expect使用举例五.expect相关错误处理 - - - - - - - - - 分割线 - - - ...
- GO编译时不避免引入外部动态库的解决方法
简介 最近碰到一个问题,有一个流量采集的组件中使用到了github.com/google/gopacket 这个库,这个库使用一切正常,但是唯独有一个缺点,编译后的二进制文件依赖于libpcap.so ...
- 通过刷题HTML遇到的问题
通过刷题HTML遇到的问题 1.有关选择器的权重问题 1.通配符选择器和继承:权重为0, 2.标签选择器:权重为0001 3.类选择器:权重为0010 4.id选择器:权重为0100 5.行内样式:权 ...
- 第一种方式:使用form表单将前端数据提交到servelt(将前端数据提交到servlet)
第二种使用Ajax的形式将前台的数据传输到后台:https://blog.csdn.net/weixin_43304253/article/details/120335657 1.form表单 引入了 ...
- 日志处理logging
前言 什么是日志?有什么作用?日志是跟踪软件运行时所发生的事件的一种方法,简单来说它可以记录某时某刻运行了什么代码,当出现问题时可以方便我们进行定位. 由python内置了一个logging模块,用户 ...