QT作为一个全面的桌面应用程序开发包,其自然提供了对图像的动画支持。本篇文章中,就来简单地在PYQt5中使用Animation动画功能实现一个足球射门的动画效果。

本篇将会依次完成以下功能:在GUI界面中显示一个图片(用一个足球做演示);

点击按钮实现足球的直线射门动画;

点击按钮实现足球的曲线射门动画;

一、在图形界面显示图片的两种方法

一般情况下,想要在GUI中显示图片,我们会通过:实例化一个QLable()部件;

实例化一个QPixmap()图形类;

通过QLabel()部件的setPixmap()方法设置QLabel()部件的图形;

就像如下代码所示:

# coding:utf-8

from PyQt5 import QtGui,QtWidgets

import sys

class MainUi(QtWidgets.QMainWindow):

def __init__(self):

super().__init__()

self.init_ui()

def init_ui(self):

self.setWindowTitle("动画使用-zmister.com") # 设置窗口标题

self.resize(400,200) # 规定窗口大小

self.main_widget = QtWidgets.QWidget() # 创建一个widget部件

self.label = QtWidgets.QLabel(self.main_widget) # 创建一个文本标签部件

png = QtGui.QPixmap() # 创建一个绘图类

png.load("logo.png") # 从pngz中加载一个图片

self.label.setPixmap(png) # 设置文本标签的图形

self.setCentralWidget(self.main_widget)

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

gui = MainUi()

gui.show()

sys.exit(app.exec_())复制代码

运行上述代码,我们将会得到如下所示的图形界面:

但是这种方法没有办法实现对图片更多的控制。为了更好地对图形界面中的图片进行控制和管理,我们还需要使用到其他的类,比如QtWidgets中的QGraphicsScene类,QGraphicsScene提供了一个场景,用于对2D图形进行管理。同时,为了展示QGraphicsScene中的内容,我们还需要使用到QtWidgets中的QGraphicsView类来提供一个视图部件。

下面,我们就通过一个简单的例子来了解一下QGraphicsScene类和QGraphicsView类的使用。

首先是完整的代码,如下所示:

# coding:utf-8

from PyQt5 import QtGui,QtWidgets,QtCore

import sys

class MainUi(QtWidgets.QMainWindow):

def __init__(self):

super().__init__()

self.init_ui()

def init_ui(self):

self.setWindowTitle("动画使用-zmister.com") # 设置窗口标题

self.resize(400,200) # 规定窗口大小

self.main_widget = QtWidgets.QWidget() # 创建一个widget部件

self.grapview = QtWidgets.QGraphicsView(self.main_widget) # 创建一个图形视图,继承自main_widget

self.grapview.setGeometry(QtCore.QRect(10, 10, 380, 180)) # 设置图形视图的矩形区域

self.scene = QtWidgets.QGraphicsScene() # 创建一个图形管理场景

self.grapview.setScene(self.scene)

png = QtGui.QPixmap() # 创建一个绘图类

png.load("logo.png") # 从png中加载一个图片

item = QtWidgets.QGraphicsPixmapItem(png) #

self.scene.addItem(item)

self.setCentralWidget(self.main_widget)

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

gui = MainUi()

gui.show()

sys.exit(app.exec_())复制代码

在这里面,基础的窗口代码与之前的代码类似,有区别且最核心的为以下几行代码。

首先,我们实例化创建了一个用于展示图形场景的图形视图QGraphicsView(),将它继承自self.main_widget主窗口部件:

self.grapview = QtWidgets.QGraphicsView(self.main_widget)复制代码

然后,我们实例化创建了一个图形场景管理类QGraphicsScene(),并通过setScene()方法将图形视图self.grapview的图形场景设置为刚刚实例化创建的QGraphicsScene():

self.scene = QtWidgets.QGraphicsScene()

self.grapview.setScene(self.scene)复制代码

最后,我们通过QPixmap()创建并加载了一个图片,将其添加到图形项目QGraphicsPixmapItem()中,并通过addItem()方法将图形项目添加到图形场景管理self.scene中:

png = QtGui.QPixmap()

png.load("logo.png")

item = QtWidgets.QGraphicsPixmapItem(png)

self.scene.addItem(item)复制代码

如此,我们就完成了通过QGraphicsView()类和QGraphicsScene()类在图形界面(GUI)中展示图片的功能,运行完整的代码,其显示出来的图形界面程序如下图所示:

二、几行代码射个门

上面我们通过两种不同的方式实现了图片在图形界面中的展示,接下来,我们借助QtCore中的QPropertyAnimation()来实现图片的动画效果。

QPropertyAnimation()类主要依靠操纵对象的QT属性来实现动画效果,其有几个比较主要的方法:start():用于启动动画;

stop():用于停止动画;

setStartValue():用于设置动画的起始值;

setEndValue():用于设置动画的结束值;

setDuration():用于设置动画的持续时间;

setKeyValueAt():用于在特定时间创建一个关键的动画帧动作;

setLoopCount():用于设置动画的循环次数;

下面我们就使用QPropertyAnimation()类实现图片的动画。为了动画的效果比5毛特效要好一点,州的先生(公众号:zmister2016)在阿里的图标库iconfont里找了一个小足球和球门的图标,嗯,就像这样:

然后,我们创建一个图形界面,里面包含一个按钮、一个小球和一个球门的图片:

# coding:utf-8

from PyQt5 import QtGui,QtWidgets,QtCore

import sys

class MainUi(QtWidgets.QMainWindow):

def __init__(self):

super().__init__()

self.init_ui()

def init_ui(self):

self.setWindowTitle("动画使用-zmister.com") # 设置窗口标题

self.resize(400,200) # 规定窗口大小

self.main_widget = QtWidgets.QWidget() # 创建一个widget部件

self.button = QtWidgets.QPushButton('射门',self.main_widget) # 创建一个按钮

self.button.setGeometry(10,10,60,30) # 设置按钮位置

self.label = QtWidgets.QLabel(self.main_widget) # 创建一个文本标签部件用于显示足球

self.label.setGeometry(50,80,50,50) # 设置足球位置

png = QtGui.QPixmap() # 创建一个绘图类

png.load("football.png") # 从png中加载一个图片

self.label.setPixmap(png) # 设置文本标签的图形

self.label.setScaledContents(True)

self.qiumen = QtWidgets.QLabel(self.main_widget) # 创建一个文本标签部件用于显示球门

self.qiumen.setGeometry(345, 75, 50, 50) # 设置球门位置

pngqiumen = QtGui.QPixmap() # 创建一个绘图类

pngqiumen.load("qiumen.png") # 从png中加载一个图片

self.qiumen.setPixmap(pngqiumen) # 设置文本标签的图形

self.setCentralWidget(self.main_widget)

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

gui = MainUi()

gui.show()

sys.exit(app.exec_())复制代码

运行上述代码,我们会得到一个如下图所示的图形界面:

我们的目的是想让图形界面中的小足球通过按钮控制,进入到球门中。接下来,我们就通过QPropertyAnimation()类来实现这个效果。

在MainUi()中新建一个名为shoot()的方法,在其中写入以下代码:

self.anim = QtCore.QPropertyAnimation(self.label,b'geometry') # 设置动画的对象及其属性

self.anim.setDuration(2000) # 设置动画间隔时间

self.anim.setStartValue(QtCore.QRect(50,80,50,50)) # 设置动画对象的起始属性

self.anim.setEndValue(QtCore.QRect(360, 90, 10, 10)) # 设置动画对象的结束属性

self.anim.start() # 启动动画复制代码

最后,我们再讲按钮的点击信号绑定到shoot()方法上:

self.button.clicked.connect(self.shoot)复制代码

完整的代码如下所示:

# coding:utf-8

from PyQt5 import QtGui,QtWidgets,QtCore

import sys

class MainUi(QtWidgets.QMainWindow):

def __init__(self):

super().__init__()

self.init_ui()

def init_ui(self):

self.setWindowTitle("动画使用-zmister.com") # 设置窗口标题

self.resize(400,200) # 规定窗口大小

self.main_widget = QtWidgets.QWidget() # 创建一个widget部件

self.button = QtWidgets.QPushButton('射门',self.main_widget) # 创建一个按钮

self.button.setGeometry(10,10,60,30) # 设置按钮位置

self.button.clicked.connect(self.shoot)

self.label = QtWidgets.QLabel(self.main_widget) # 创建一个文本标签部件用于显示足球

self.label.setGeometry(50,80,50,50) # 设置足球位置

png = QtGui.QPixmap() # 创建一个绘图类

png.load("football.png") # 从png中加载一个图片

self.label.setPixmap(png) # 设置文本标签的图形

self.label.setScaledContents(True) # 图片随文本部件的大小变动

self.qiumen = QtWidgets.QLabel(self.main_widget) # 创建一个文本标签部件用于显示球门

self.qiumen.setGeometry(345, 75, 50, 50) # 设置球门位置

pngqiumen = QtGui.QPixmap() # 创建一个绘图类

pngqiumen.load("qiumen.png") # 从png中加载一个图片

self.qiumen.setPixmap(pngqiumen) # 设置文本标签的图形

self.setCentralWidget(self.main_widget)

def shoot(self):

self.anim = QtCore.QPropertyAnimation(self.label,b'geometry') # 设置动画的对象及其属性

self.anim.setDuration(2000) # 设置动画间隔时间

self.anim.setStartValue(QtCore.QRect(50,80,50,50)) # 设置动画对象的起始属性

self.anim.setEndValue(QtCore.QRect(360, 90, 10, 10)) # 设置动画对象的结束属性

self.anim.start() # 启动动画

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

gui = MainUi()

gui.show()

sys.exit(app.exec_())复制代码

运行上述代码,点击“射门”按钮,我们将会得到如下动图所示的动画:

这样,通过QPropertyAnimation()的setDuration()方法、setStartValue()方法、setEndValue()方法我们就实现了一个简单的动画。

三、圆月弯刀继续射门

但是上面的射门动画是一条直线将小足球移动到了球门之内,简单粗暴欠缺了些许美感,下面,我们让这个射门换一种方式,用圆月弯刀的香蕉球将小足球射入球门。

还记得上面我们提过QPropertyAnimation()的setKeyValueAt()这个用于设置动画关键帧的方法。现在我们就将利用它来实现足球射门时的曲线。

与上面的图形界面的代码不一样的是,我们需要绘制一条曲线线条来作为足球射门时的路径。所以我们需要对上面的图形界面的代码进行一些修改:

# coding:utf-8

from PyQt5 import QtGui,QtWidgets,QtCore

import sys

class MainUi(QtWidgets.QMainWindow):

def __init__(self):

super().__init__()

self.init_ui()

def init_ui(self):

self.setWindowTitle("动画使用-州的先生zmister.com") # 设置窗口标题

self.resize(400,200) # 规定窗口大小

self.main_widget = QtWidgets.QWidget() # 创建一个widget部件

self.button = QtWidgets.QPushButton('射门',self.main_widget) # 创建一个按钮

self.button.setGeometry(10,10,60,30) # 设置按钮位置

self.label = QtWidgets.QLabel(self.main_widget) # 创建一个文本标签部件用于显示足球

self.label.setGeometry(50,150,50,50) # 设置足球位置

png = QtGui.QPixmap() # 创建一个绘图类

png.load("football.png") # 从png中加载一个图片

self.label.setPixmap(png) # 设置文本标签的图形

self.label.setScaledContents(True) # 图片随文本部件的大小变动

self.qiumen = QtWidgets.QLabel(self.main_widget) # 创建一个文本标签部件用于显示球门

self.qiumen.setGeometry(345, 75, 50, 50) # 设置球门位置

pngqiumen = QtGui.QPixmap() # 创建一个绘图类

pngqiumen.load("qiumen.png") # 从png中加载一个图片

self.qiumen.setPixmap(pngqiumen) # 设置文本标签的图形

self.path = QtGui.QPainterPath() # 实例化一个绘制类,用于绘制动作

self.path.moveTo(50, 150)

self.path.cubicTo(50, 150, 50, 20, 370, 90)

self.setCentralWidget(self.main_widget)

# 重写patintEvent()方法

def paintEvent(self, e):

qp = QtGui.QPainter()

qp.begin(self)

qp.drawPath(self.path) # 在图形界面上根据self.path绘制一条线条

qp.end()

if __name__ == '__main__':

app = QtWidgets.QApplication(sys.argv)

gui = MainUi()

gui.show()

sys.exit(app.exec_())复制代码

在上面的代码中,与之前的程序代码有一下不同之处:

我们实例化创建了一个QtGui.QPainterPath(),用于进行绘制操作。通过它的moveTo()方法,设置了绘制的起始点,通过它的cubicTo()方法,设置的绘制的整个路径:

self.path = QtGui.QPainterPath() # 实例化一个绘制类,用于绘制动作

self.path.moveTo(50, 150)

self.path.cubicTo(50, 150, 50, 20, 370, 90)复制代码

接着,我们重写了窗口的paintEvent()方法,根据绘制操作的定义,在图形上绘制一条相应的线条:

def paintEvent(self, e):

qp = QtGui.QPainter()

qp.begin(self)

qp.drawPath(self.path) # 在图形界面上根据self.path绘制一条线条

qp.end()复制代码

这样,我们的图形界面程序呈现出来的就是如下图所示的样子:

图形上呈现了我们设置的足球将要运动的轨迹,接下来,我们通过QPropertyAnimation()的setKeyValueAt()设置关键帧的路径,来实现足球曲线射门,具体操作同样在shoot()方法中进行:

def shoot(self):

self.anim_x = QtCore.QPropertyAnimation(self.label, b'geometry') self.anim_x.setDuration(3000)

self.anim_x.setStartValue(QtCore.QRect(50,150,50,50)) # 设置动画对象的起始属性

positionValues = [n / 10 for n in range(0, 10)]

for n,i in enumerate(positionValues):

x = self.path.pointAtPercent(i).x()

y = self.path.pointAtPercent(i).y()

z = 50 - n*3.5

self.anim_x.setKeyValueAt(i,QtCore.QRect(x, y,z,z))

self.anim_x.setEndValue(QtCore.QRect(360, 90, 10, 10))

self.anim_x.start()复制代码

最后,同样将“射门”按钮的点击信号绑定在shoot()方法上。运行程序代码,点击“射门”按钮,将会出现如下动图所示的动画效果:

为了更加的美观,其实可以将重写的paintEvent()去掉,在这里为了演示路径,就没有去除。

在PyQt5中使用动画是不是很简单?有问题欢迎留言讨论。

python模拟足球射门_Python玩个球,如何用PyQt5实现足球射门动画?相关推荐

  1. python模拟抛硬币_python实现简单随机模拟——抛呀抛硬币

    还是在上次提到的数据之魅那本书,看到模拟这章,有个python模拟脚本,但书上不全,就自己简单写了下. 流程:在不同的平衡参数p(为0.5时为均匀的)下,模拟60次实验,每次投硬币8次,统计正面朝上的 ...

  2. python模拟浏览器代码_python 模拟浏览器

    想用python模拟浏览器访问web的方法测试些东西,有哪几种方法呢? 一类:单纯的访问web,不解析其js,css等. 1. urllib2 #-*- coding:utf-8 -* import ...

  3. python模拟键盘打字_python模拟鼠标点击和键盘输入的操作

    所有代码都是网上百度出来的,通过个人实践找到适合自己的. 采用的python 库是 pymouse.pykeyboard 安装时直接pip安装的,pip install PyUserInput 实现了 ...

  4. python模拟登录网站_Python模拟登录淘宝都实现了,你还怕模拟登录?

    文章转载自公众号 :裸睡的猪 , 作者 猪哥66 最近想爬取淘宝的一些商品,但是发现如果要使用搜索等一些功能时基本都需要登录,所以就想出一篇模拟登录淘宝的文章! 看了下网上有很多关于模拟登录淘宝,但是 ...

  5. python模拟全部代码_Python模拟登陆实现代码

    下面分享一个使用Python进行网站模拟登陆的小例子. 原理 使用Cookie技术,绕开网站登录验证.要使用到cookielib库.流程: 创建一个保存Cookie的容器,可选的有CookieJar, ...

  6. python 模拟鼠标键盘_python之模拟鼠标键盘动作

    上个月就打算开发个还算好玩的项目,但是一直没时间.这篇是此项目用到的一部分, 处理好此部分基本还差通信等方面的了.首先模拟鼠标键盘按下释放的动作,本人利用X11 这个库,所以要了解X11编程;其次,本 ...

  7. python 模拟登录验证码_Python模拟登陆 —— 征服验证码 3 CSDN

    CSDN使用了spring的webflow 这个隐藏参数可以理解成每个需要登录的用户都有一个流水号.只有有了webflow发放的有效的流水号,用户才可以说明是已经进入了webflow流程.否则,没有流 ...

  8. python扫雷 高级算法_Python玩转算法—扫雷

    此题来自LeetCode上的一道难度为Medium的题,说是有一张玩到一半的扫雷地图,接下来给你指定一个点击位置,让你预测点击之后,地图将发生怎么样的变化.看到这道题,瞬间让我想起了以前玩扫雷的日子, ...

  9. python模拟登录网站_Python爬虫实战之(四)| 模拟登录京东商城

    作者:xiaoyu 微信公众号:Python数据科学 知乎:Python数据分析师 前两篇和大家分享了爬虫中http的一些概念和使用方法,基础篇我们主要介绍了http的请求头,高级篇我们主要介绍了co ...

最新文章

  1. opencv图像旋转
  2. 科大讯飞刷新SQuAD 2.0问答榜纪录,机器阅读理解全面超越人类
  3. Linux命令学习记录(六)
  4. c语言结构体老师信息管理系统,C语言课程设计职工信息管理系统结构体数组实现程序源代码.doc...
  5. 移动端html游戏开发,GitHub - PromeYang/GameBuilder: GameBuilder 是移动端轻量HTML5游戏快速开发框架,主要应用于活动推广。...
  6. c语言中变量有几种存储方式,C语言变量的存储类别有哪些详细资料介绍
  7. Zynq7000系列之芯片引脚功能综述
  8. 【渝粤教育】电大中专市场营销管理 (2)作业 题库
  9. excel 两列模糊匹配给出结果_北大硕士给大脑植入Excel病毒,工作效率提升了好几倍...
  10. java和Mysql数据一致性_java web开发中数据一致性的问题
  11. 2 python全局变量如何指定(是在模块内,还是函数内)
  12. 51nod 1605:棋盘问题
  13. 学习LaTex:常用符号总结
  14. LibreOJ β Round #2 E. 数论只会 GCD
  15. MATLAB2016b安装包
  16. 推荐oracle exadata,Exadata的一些常见误区
  17. 网络安全职业_如何开始网络安全职业
  18. 2040: [蓝桥杯2022初赛] 砍竹子(优先队列)
  19. SEO内页优化,SEO内容优化,内页快速SEO优化
  20. 【First-order Methods】 5 Smoothness and Strong Convexity

热门文章

  1. 【二分匹配】 HDOJ 3118
  2. 计算机学院与软件学院区别,计算机学院和软件学院的专业上有什么区别?
  3. 14.CPU调度——CPU调度策略
  4. Java 字节数组流之图片转成字节数组
  5. 离线数仓搭建_16_Azkaban全流程调度
  6. oracle数据变化记录,学习笔记:Oracle伪列函数ora_rowscn 记录表中行数据的修改时间...
  7. pandas给读取到的excel添加表头
  8. Java岗大厂面试百日冲刺【Day41】— JVM3 (日积月累,每日三题)
  9. Java版工程项目管理系统平台+java版企业工程系统源码+助力工程企业实现数字化管理
  10. 全屏网格折叠动画插件 1