写一个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 ...
随机推荐
- 8. Ceph 基础篇 - 运维常用操作
文章转载自:https://mp.weixin.qq.com/s?__biz=MzI1MDgwNzQ1MQ==&mid=2247485300&idx=1&sn=aacff9f7 ...
- MySQL 的七种日志总结
文章转载自:https://mp.weixin.qq.com/s/ewv7HskHvH3O7kFyOmoqgw 一.MySQL 日志分类 日志类别 说明 备注 错误日志 错误日志记录了当MySQL启动 ...
- centos7安装sonarqube-9.2.4
官方文档地址:https://docs.sonarqube.org/latest/requirements/requirements/ 使用 sonarqube 对 java 项目代码进行扫描的时候, ...
- 阿里云SLB的健康检查配置
若阿里云SLB健康检查异常,则默认SLB无法访问到后端ECS,也就意味着通过SLB访问后端ECS上部署的服务会报502 gateway. 另一种办法是关闭健康检查(不推荐) 简要说明: SLB通过配置 ...
- Elasticsearch中的一些重要概念:cluster, node, index, document, shards及replica
首先,我们来看下一下如下的这个图: Cluster Cluster也就是集群的意思.Elasticsearch集群由一个或多个节点组成,可通过其集群名称进行标识.通常这个Cluster 的名字是可以在 ...
- 0-mysql数据库下载及安装
1 下载mysql源安装包 wget http://dev.mysql.com/get/mysql57-community-release-el7-8.noarch.rpm 2 安装mysql源 yu ...
- H5调用微信支付
这里用的是 vue项目; 首先在mounted中判断是否有openId,如果没有,则去获取 let openid = localStorage.getItem('openid'); if (!open ...
- Optional 常用方法总结
转载请注明出处: Optional 类是 JAVA 8 提供的判断程序是否为空提供的包装工具类:可以减少代码中的 是否为空的判断,以及减少 NullPointerExceptions:使得程序变得更为 ...
- Vue+vant移动端处理弹窗不能滑动问题
自己在做项目开发时,使用vantUI组件,在项目中遇到了弹窗组件里面当内容过多时,会出现滚动卡顿或者不能滚动问题,开始一直以为是自己的样式写的有问题,检查下来才发现并不是,而是弹窗组件的问题,于是找到 ...
- prometheus监控实战
第一节.环境和软件版本 1.1.操作系统环境 主机ip 操作系统 部署软件 备注 192.168.10.10 Centos7.9 Grafana.Pushgateway.Blackbox Export ...