用Python 把罗小黑养在自己桌面

发布于 2021-04-29 07:20

作者 | 李秋键

责编 | 寇雪芹

出品 | AI科技大本营(ID:rgznai100)

引言:

了解过我们之前文章的都知道我们曾经做过一个智能桌宠项目。但是很显然那个程序过于卡段。故这一次我们将重新制作个智能桌宠项目,不同于之前的项目在于,之前使用了大量的jpg图片替换造成了卡顿现象。而这一次我们将不会采用这种方式,具体见下面代码讲解。文末附源码。

效果图


01

系统概述


首先,我们只做桌宠的目的是为了方便操作电脑,故这一版本将包含搭建免python环境去运行程序。即可以在没有安装python的电脑上运行桌宠程序,但过程有些复杂,只会在文末给出免安装的程序。


02

代码流程讲解


2.1 导入库:

在这里我们使用到了用os设置程序QT环境的问题。通过使用下述代码可以实现对环境的设置,这里是为了免环境程序的搭建而使用。如果我们不用可以去除这个代码:

1os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = "Lib\site-packages\PyQt5\Qt\plugins"

然后导入其他所使用到的库:

1import os
2os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = "Lib\site-packages\PyQt5\Qt\plugins"
3import sys
4from PyQt5.QtGui import *
5from PyQt5.QtCore import *
6from PyQt5.QtWidgets import *
7from PyQt5 import QtWidgets, QtGui
8# 导入QT,其中包含一些常量,例如颜色等
9from PyQt5.QtCore import Qt
10# 导入常用组件
11from PyQt5.QtWidgets import QApplication, QMainWindow
12from PyQt5.QtWidgets import QLabel
13from threading import Thread
14# 使用调色板等
15from PyQt5.QtGui import QIcon, QMovie
16import time
17import os
18import random


2.2 设置程序整体的初始化:

程序界面的初始化包括如下内容:

(1)不规则窗口的建立;实现不规则窗口的最简单方式就是图片素材不仅当遮罩层,还当背景图片,通过重载paintEvent()函数绘制窗口背景; 使用函数setMask(self,QBitmap)setMask(self,QRegion)。setMask()的作用是为调用它的控件增加一个遮罩,遮住所选区域以外的部分,使之看起来是透明的,它的参数可以为QBitmap或QRegion对象,此处调用QPixmap的mask()函数获得图片自身的遮罩,是一个QBitmap对象,在实例中使用的是PNG格式的图片,它的透明部分就是一个遮罩

1super(DemoWin, self).__init__()
2self.initUI()
3# 初始化,不规则窗口
4self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)
5self.setAutoFillBackground(False)
6self.setAttribute(Qt.WA_TranslucentBackground, True)
7self.repaint()

(2)鼠标初始化,这里设置鼠标的作用主要是为了能够实现鼠标拖动桌宠的效果。

1# 是否跟随鼠标
2self.is_follow_mouse = False
3self.move(1650,20)

(3)语料库的初始化,这里设置语料库在data.txt中。桌宠弹出的对话所搜索的txt内容也可以按照自己的需求修改。

1with open("data.txt""r"as f:
2    text = f.read()
3    self.sentence = text.split("\n")

(4)设置托盘图标。因为考虑到桌宠在不需要的时候方便管理,设置托盘图标可以随时隐藏桌宠和显示桌宠:

1# 设置托盘选项
2iconpath="1.jpg"

(5)设置右键菜单功能的初始化 :

1#右键菜单
2quit_action = QAction(u'退出', self, triggered=self.quit)
3quit_action.setIcon(QIcon(iconpath))
4showwin = QAction(u'显示', self, triggered=self.showwin)
5self.tray_icon_menu = QMenu(self)
6self.tray_icon_menu.addAction(showwin)
7self.tray_icon_menu.addAction(quit_action)
8self.tray_icon = QSystemTrayIcon(self)
9self.tray_icon.setIcon(QIcon(iconpath))
10self.tray_icon.setContextMenu(self.tray_icon_menu)
11self.tray_icon.show()

(6)透明窗口:

1#窗口透明程度
2self.setWindowOpacity(1)

(7)设置对话框,为鼠标长时间停留的对话框:

1# 对话框
2QToolTip.setFont(QFont('楷体'14))
3y = ['不要随便摸人家啦''每次见到主人都很开心呀''话说最近主人都没理我诶''再摸我的话小心我生气了''恭喜发财大吉大利']
4self.setToolTip(random.choice(y))
5# 每隔一段时间做个动作
6self.timer = QTimer()
7self.timer.timeout.connect(self.randomAct)
8self.timer.start(7000)
9self.condition = 0
10self.talk_condition=0

(8)设置桌宠具有随机动作:

1# 每隔一段时间做个动作
2self.timer1 = QTimer()
3self.timer1.timeout.connect(self.talk)
4self.timer1.start(5000)
5self.pet1 = []
6for i in os.listdir("biu"):
7    self.pet1.append("biu/" + i)


2.3 设置GUI界面的初始化:

内容包括窗口大小位置标题等定义,具体见如下代码,都有做注解:

1def initUI(self):
2    # 将窗口设置为动图大小
3    self.resize(400400)
4    self.label1 = QLabel(""self)
5    self.label1.setStyleSheet("font:15pt '楷体';border-width: 1px;color:blue;")  # 设置边框
6    # 使用label来显示动画
7    self.label = QLabel(""self)
8    # label大小设置为动画大小
9    self.label.setFixedSize(200200)
10    # 设置动画路径
11    self.movie = QMovie("./biu/biu12.gif")
12    #宠物大小
13    self.movie.setScaledSize(QSize(200200))
14    # 将动画添加到label中
15    self.label.setMovie(self.movie)
16    # 开始播放动画
17    self.movie.start()
18    #透明窗口
19    #self.setWindowOpacity(1)
20    # 添加窗口标题
21    self.setWindowTitle("GIFDemo")


2.4 设置鼠标拖动功能:

鼠标拖动功能其实就是鼠标和窗口的绑定和移动解绑。即鼠标左键按下时, 宠物将和鼠标位置绑定;然后鼠标移动, 则宠物也移动;接着鼠标释放时, 取消绑定。代码如下:

1'''鼠标左键按下时, 宠物将和鼠标位置绑定'''
2def mousePressEvent(self, event):
3    if event.button() == Qt.LeftButton:
4        self.is_follow_mouse = True
5        self.mouse_drag_pos = event.globalPos() - self.pos()
6        event.accept()
7        self.setCursor(QCursor(Qt.OpenHandCursor))
8        self.movie = QMovie("./biu/biu10.gif")
9        # 宠物大小
10        self.movie.setScaledSize(QSize(200200))
11        # 将动画添加到label中
12        self.label.setMovie(self.movie)
13        # 开始播放动画
14        self.movie.start()
15'''鼠标移动, 则宠物也移动'''
16def mouseMoveEvent(self, event):
17    if Qt.LeftButton and self.is_follow_mouse:
18        self.move(event.globalPos() - self.mouse_drag_pos)
19        event.accept()
20'''鼠标释放时, 取消绑定'''
21def mouseReleaseEvent(self, event):
22    self.is_follow_mouse = False
23    self.setCursor(QCursor(Qt.ArrowCursor))


2.5 设置鼠标移入时变换:

设置鼠标碰到桌宠时变成小手的状态,这样更卡通化,显得更亲近:

1def