查看原文
其他

如何从零开始制作智能桌宠?

李秋键 CSDN 2019-12-18
作者 | 李秋键
责编 | maozz
出品 | CSDN(ID:CSDNnews)
引言:是否还记得曾经风靡全国的QQ宠物呢,那个又调皮又可爱的QQ企鹅,偶尔还会生病撒娇,需要培养的虚拟宠物,你是否还记得它的样子呢。它是腾讯公司推出的第一款QQ宠物系列游戏,也是运营了很久的系列宠物游戏。该游戏无级别限制,贯穿宠物成长全过程,包括打工、学习、旅游、游戏、结婚、生蛋等。但是该游戏已于2018年9月14日下架,全服关闭,我们为此感到可惜,但是今天我们就将走上他们曾经的制作之路实现我们的桌面宠物,手把手从零制作。而今天我们就将借助python实现自己的宠物,会说话,并且还可以控制电脑等智能功能,首先让我们看一下我们的效果。


桌宠的特点

其特点之一:
会运动,还会变身:
特点之二:
会说话聊天。
特点之二:
右键多功能性(可语音控制,连接WiFi等,最主要学完这篇文章之后可以自己添加功能)。

程序前的准备

首先我们需要有python的环境,并且安装了pyqt5库。接着我们需要准备宠物图片,因为连续的图片更换才形成了图片,如下图所示:

编写程序界面预处理

其中包括1、透明窗口类:
class newWindow(QWidget):
    def __init__(self, parent=None):
        super(newWindow, self).__init__(parent)
        self.i = 1
        self.mypix()
        self.move(1750,50)
        self.timer = QTimer()
        self.timer.setInterval(500)
        self.timer.timeout.connect(self.timeChanged)
        self.timer.start()
        self.setWindowFlags(Qt.FramelessWindowHint)  # 去除界面边框
        self.setWindowFlags(Qt.WindowStaysOnTopHint)  
        self.setAttribute(Qt.WA_TranslucentBackground)  # 背景透明
        self.setMouseTracking(False)  # 设置鼠标移动跟踪是否有效
        self.initUI()
2、添加可运动效果,即动画:
def mypix1(self):
            self.update()
            if self.i == 6:#散步
               time.sleep(5)
            elif self.i ==11:#甩膀子
                time.sleep(1)
            elif self.i ==16:#唱歌
                time.sleep(1)
            elif self.i ==21:#拖东西
                time.sleep(1)
            elif self.i ==26:#坐在地上无聊
                time.sleep(1)
            elif self.i ==31:#坐在地上沮丧
                time.sleep(1)
            elif self.i ==36:#爬起来
                time.sleep(1)
            elif self.i ==43:#准备变红
                time.sleep(1)
            elif self.i ==48:#变红
                time.sleep(1)
            elif self.i ==54:#红色状态
                time.sleep(1)
            elif self.i ==56:#返回
                self.i = 1
                time.sleep(2)
            self.mypic = {1'.\img\shime1.png'2'.\img\shime1.png'3'.\img\shime1.png'4'.\img\shime1.png',5'.\img\shime1.png',6'.\img\shime2.png',7'.\img\shime3.png',8'.\img\shime2.png',
    9'.\img\shime3.png' , 10'.\img\shime3.png',11'.\img\shime5.png',12'.\img\shime6.png',13'.\img\shime5.png',14'.\img\shime6.png'15'.\img\shime6.png',16'.\img\shime47.png',
    17'.\img\shime48.png',18'.\img\shime49.png',19'.\img\shime50.png',20'.\img\shime50.png',21'.\img\shime38.png',22'.\img\shime39.png',23'.\img\shime40.png',24'.\img\shime41.png',
    25'.\img\shime30.png',26'.\img\shime31.png',27'.\img\shime32.png',28'.\img\shime33.png',29'.\img\shime33.png',30'.\img\shime16.png',31'.\img\shime15.png',32'.\img\shime16.png' ,
    33'.\img\shime17.png',34'.\img\shime18.png',35'.\img\shime19.png',36'.\img\shime19.png',37'.\img\shime19.png',38'.\img\shime20.png',39'.\img\shime20.png',40'.\img\shime21.png' ,
    41'.\img\shime22.png',42'.\img\shime26.png',43'.\img\shime27.png',44'.\img\shime28.png',45'.\img\shime29.png',46'.\img\shime30.png',47'.\img\shime47.png',48'.\img\shime46.png',
    49'.\img\shime45.png',50'.\img\shime44.png',51'.\img\shime43.png',52'.\img\shime42.png',53'.\img\shime42.png',54'.\img\shime43.png',55'.\img\shime42.png',56'.\img\shime43.png'}
            self.pix = QPixmap(self.mypic[self.i], '0', Qt.AvoidDither | Qt.ThresholdAlphaDither | Qt.ThresholdDither)
            self.resize(self.pix.size())
            self.setMask(self.pix.mask())
            self.dragPosition = None
3.添加鼠标移动可拖拉宠物位置:
def mousePressEvent(self, event):  
        QtCore.Qt.NoButton - 0 - 没有按下鼠标键
        QtCore.Qt.LeftButton -1 -按下鼠标左键
        QtCore.Qt.RightButton -2 -按下鼠标右键
        QtCore.Qt.Mion 或 QtCore.Qt.MiddleButton -4 -按下鼠标中键
        nn = event.buttons() 
    def mouseReleaseEvent(self, event):  
        print('鼠标键放开了')
        # 显示不规则图片
    def mypix(self):
         self.update()
self.pix=QPixmap('.\img\shime1.png','0',Qt.AvoidDither|Qt.ThresholdAlphaDither|Qt.ThresholdDither)
         self.resize(self.pix.size())
         self.setMask(self.pix.mask())
def mouseMoveEvent(self, event):  # 鼠标键移动时调用
        ret = self.hasMouseTracking()
        #print('鼠标移动了:%s' % ret)
        x = event.x()  # 返回鼠标相对于窗口的x轴坐标
        y = event.y()  # 返回鼠标相对于窗口的y轴坐标
       # print('鼠标x坐标:%s ,鼠标y坐标:%s' % (x, y))
        xy = event.pos()
        s = self.mapToGlobal(xy)  # 将窗口坐标转换成屏幕坐标.属于QWidget类的方法;参数类型QPoint
        #print('鼠标x坐标:%s ,鼠标y坐标:%s' % (s.x(), s.y()))
        self.move(s.x()-75, s.y()-100)
        self.update()
        self.pix = QPixmap('.\img\shime4.png''0', Qt.AvoidDither | Qt.ThresholdAlphaDither | Qt.ThresholdDither)
        self.resize(self.pix.size())
        self.setMask(self.pix.mask())
        xy1 = event.globalPos()  # 返回鼠标相对于屏幕的坐标。PyQt5.QtCore.QPoint(1096, 37)【用xy1.x()  xy1.y()提取值】
        s1 = self.mapFromGlobal(xy1)  # 将屏幕坐标转换成窗口坐标.属于QWidget类的方法;参数类型QPoint
        # mapToParent(QPoint) - 将窗口坐标转换成父窗口坐标。如果没有父窗口,则相当于mapToGlobal (QPoint)
        # mapFromParent(QPoint) - 将父窗口坐标转换成窗口坐标。如果没有父窗口,则相当于mapFromGlobal(QPoint)
        # mapTo (QWidget, QPoint) - 将窗口坐标转换成 QWidget父窗口坐标
        px = event.globalX()  # 返回相对于屏幕的x坐标
        py = event.globalY()  # 返回相对于屏幕的y坐标
        s = event.windowPos()  # 相对于窗口的坐标(保留一位小数),PyQt5.QtCore.QPointF(481.0, 1.0)【用s.x()  s.y()提取值】
        p = event.screenPos()  # 相对于屏幕的坐标(保留一位小数).PyQt5.QtCore.QPointF(476.0, 49.0)【用p.x()  p.y()提取值】
        t = event.timestamp()  
4.添加鼠标右键多功能性(可以自己多添加功能):
def contextMenuEvent(self, e):
"""右键菜单"""
cmenu = QMenu(self)
act1 = cmenu.addAction("语音聊天")
act2 = cmenu.addAction("语音控制")
act3 = cmenu.addAction("WiFi连接")
act4 = cmenu.addAction("关机")
act5 = cmenu.addAction("退出")
act6 = cmenu.addAction("待续")
action = cmenu.exec_(self.mapToGlobal(e.pos()))
if action == act5:
qApp.quit()
elif action == act1:
os.system("python F:/代码/python/语音识别/语音聊天机器人/user.py")
elif action == act2:
os.startfile(r"F:\代码\python\语音识别\语音智能控制\recognize.exe")
elif action == act3:
os.startfile(r'C:\Users\asus\Desktop\功能\断网连接.vbs')
elif action == act4:
os.system("shutdown -p")
elif action == act6:
 self.parent_window.show()
5.调动封装程序:
if __name__ == '__main__':
    app = QApplication(sys.argv)
    demo = newWindow()
    demo.show()
sys.exit(app.exec())

最终效果

 要么至此主要的关键代码及其流程已经给了出来,其中宠物的图片素材可以自己寻找替换掉就可以制作属于自己的宠物啦,并且最主要的是我们给他添加了一些语音控制等等可以控制电脑的功能,这样又实用又有趣,是不是学到了很多呢,当然至此还没有结束。
下面我们将对其中的一些知识和准备做一些介绍,其中最关键的是在于pyQT5模块的使用和安装。
pyQt5应用框架和Python相关性。Pyqt5支持Python2.x和Python3.x版本。
PyQt5以一套Python模块的形式来实现功能。它包含了超过620个类,600个方法和函数。它是一个多平台的工具套件,它可以运行在所有的主流操作系统中,包含Unix,Windows和Mac OS。PyQt5采用双重许可模式。开发者可以在GPL和社区授权之间选择。
PyQt5的类被划分在几个模块中,下面列出了这些模块:
  • QtCore :模块包含了非GUI的功能设计。这个模块被用来实现时间,文件和目录,不同数据类型,流,URL,mime类型,线程和进程。
  • QtGui:模块包含的类用于窗口化的系统结构,事件处理,2D绘图,基本图形,字体和文本。
  • QtWidgets:模块包含的类提供了一套UI元素来创建经典桌面风格用户界面。
  • QtMultimedia:模块包含的类用于处理多媒体内容和链接摄像头和无线电功能的API。
  • QtBluetooth:模块包含的类用于扫描蓝牙设备,并且和他们建立连接互动。
  • QtNetwork:模块包含的类用于网络编程,这些类使TCP/IP和UDP客户端/服务端编程更加容易和轻便。
  • QtPositioning:模块包含的类用于多种可获得资源的位置限定,包含卫星定位,Wi-Fi,或一个文本文件。
  • Enginio:模块用于解决客户端访问Qt云服务托管。
  • QtWebSockets:模块用于解决客户端访问Qt云服务托管。
  • QtWebKit:包含的关于浏览器的类用于解决基于WebKit2的支持库。
  • QtWebKitWidgets:模块包含的关于WebKit1的类基本解决浏览器使用基于QtWidgets应用问题。 
  • QtXml:QtXml 模块包含的类用于解析XML文件。这个模块提供SAX和DOM API解决方法。
  • QtSvg:模块提供类用于显示SVG文件内容。Scalable Vector Graphics (SVG) 是一种语言,用XML来描述二维图形和图形应用程序。
  • QtSql:模块提供类驱动数据库工作。 
  • QtTest:模块包含了方法提供PyQt5应用的单元测试。
PyQt5不向后兼容PyQt4;这是一些在PyQt5中的重要改变。然而,将旧代码迁移到新的版本中并不是非常困难。不同点如下:
  • Python 模块已经被改写. 一些模块被舍弃 (QtScript), 部分的模块被分割成子模块 (QtGui, QtWebKit).
  • 新的模块被引进, 包含 QtBluetooth, QtPositioning, 和 Enginio.
  • PyQt5 只支持最新风格的信号和槽的写法. SIGNAL()和SLOT()的调用将不会被长时间支持.
  • PyQt5 不支持任何在Qt 5.0版本中弃用或取消的API.
其中模块的安装方法:
PyQt5安装,在cmd下输入pip install PyQt5,完成PyQt5安装,再安装qt designer,如果qt designer无法使用pip安装,可以下载whl文件安装。
声明:本文系作者投稿。

热 文 推 荐 

☞「刷新 CTO」微软与 CSDN 的 CTO 转型思想汇
☞干货收藏!史上最强 Tomcat 8 性能优化来啦!| 原力计划
☞TIOBE 12 月编程语言排行榜:争夺年度编程语言,Java、C、Python、C# 即将开战!
C、C++ 不得宠,微软正开发新的编程语言!
华为鸿蒙 OS 2020 计划曝光!手机仍然优先用安卓

用象棋的思维趣说 IT 人的职业发展和钱途

那些打着AI万金油旗号的产品欺骗大众,如何识别?

详谈4大主流CPU处理器技术架构

点击阅读原文,即刻报名!
你点的每个“在看”,我都认真当成了喜欢

    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存