成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

使用PyQt5的動(dòng)畫功能實(shí)現(xiàn)足球射門效果

stefanieliang / 1049人閱讀

摘要:作為一個(gè)全面的桌面應(yīng)用程序開(kāi)發(fā)包,其自然提供了對(duì)圖像的動(dòng)畫支持。本篇文章中,就來(lái)簡(jiǎn)單地在中使用動(dòng)畫功能實(shí)現(xiàn)一個(gè)足球射門的動(dòng)畫效果。還記得上面我們提過(guò)的這個(gè)用于設(shè)置動(dòng)畫關(guān)鍵幀的方法。在中使用動(dòng)畫是不是很簡(jiǎn)單有問(wèn)題歡迎留言討論。

QT作為一個(gè)全面的桌面應(yīng)用程序開(kāi)發(fā)包,其自然提供了對(duì)圖像的動(dòng)畫支持。本篇文章中,就來(lái)簡(jiǎn)單地在PYQt5中使用Animation動(dòng)畫功能實(shí)現(xiàn)一個(gè)足球射門的動(dòng)畫效果。

本篇將會(huì)依次完成以下功能:

在GUI界面中顯示一個(gè)圖片(用一個(gè)足球做演示);

點(diǎn)擊按鈕實(shí)現(xiàn)足球的直線射門動(dòng)畫;

點(diǎn)擊按鈕實(shí)現(xiàn)足球的曲線射門動(dòng)畫;

本文首發(fā)州的先生博客:Python GUI教程(十五):在PyQt5中使用動(dòng)畫,轉(zhuǎn)載請(qǐng)注明出處
一、在圖形界面顯示圖片的兩種方法

一般情況下,想要在GUI中顯示圖片,我們會(huì)通過(guò):

實(shí)例化一個(gè)QLable()部件;

實(shí)例化一個(gè)QPixmap()圖形類;

通過(guò)QLabel()部件的setPixmap()方法設(shè)置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("動(dòng)畫使用-zmister.com") # 設(shè)置窗口標(biāo)題
        self.resize(400,200) # 規(guī)定窗口大小
        self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個(gè)widget部件
        self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個(gè)文本標(biāo)簽部件
        png = QtGui.QPixmap() # 創(chuàng)建一個(gè)繪圖類
        png.load("logo.png") # 從pngz中加載一個(gè)圖片
        self.label.setPixmap(png) # 設(shè)置文本標(biāo)簽的圖形
        self.setCentralWidget(self.main_widget)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    gui = MainUi()
    gui.show()
    sys.exit(app.exec_())

運(yùn)行上述代碼,我們將會(huì)得到如下所示的圖形界面:

但是這種方法沒(méi)有辦法實(shí)現(xiàn)對(duì)圖片更多的控制。為了更好地對(duì)圖形界面中的圖片進(jìn)行控制和管理,我們還需要使用到其他的類,比如QtWidgets中的QGraphicsScene類,QGraphicsScene提供了一個(gè)場(chǎng)景,用于對(duì)2D圖形進(jìn)行管理。同時(shí),為了展示QGraphicsScene中的內(nèi)容,我們還需要使用到QtWidgets中的QGraphicsView類來(lái)提供一個(gè)視圖部件。

下面,我們就通過(guò)一個(gè)簡(jiǎn)單的例子來(lái)了解一下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("動(dòng)畫使用-zmister.com") # 設(shè)置窗口標(biāo)題
        self.resize(400,200) # 規(guī)定窗口大小
        self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個(gè)widget部件

        self.grapview = QtWidgets.QGraphicsView(self.main_widget) # 創(chuàng)建一個(gè)圖形視圖,繼承自main_widget
        self.grapview.setGeometry(QtCore.QRect(10, 10, 380, 180)) # 設(shè)置圖形視圖的矩形區(qū)域
        self.scene = QtWidgets.QGraphicsScene() # 創(chuàng)建一個(gè)圖形管理場(chǎng)景
        self.grapview.setScene(self.scene)
        png = QtGui.QPixmap() # 創(chuàng)建一個(gè)繪圖類
        png.load("logo.png") # 從png中加載一個(gè)圖片
        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_())

在這里面,基礎(chǔ)的窗口代碼與之前的代碼類似,有區(qū)別且最核心的為以下幾行代碼。

首先,我們實(shí)例化創(chuàng)建了一個(gè)用于展示圖形場(chǎng)景的圖形視圖QGraphicsView(),將它繼承自self.main_widget主窗口部件:

self.grapview = QtWidgets.QGraphicsView(self.main_widget)

然后,我們實(shí)例化創(chuàng)建了一個(gè)圖形場(chǎng)景管理類QGraphicsScene(),并通過(guò)setScene()方法將圖形視圖self.grapview的圖形場(chǎng)景設(shè)置為剛剛實(shí)例化創(chuàng)建的QGraphicsScene():

self.scene = QtWidgets.QGraphicsScene()
self.grapview.setScene(self.scene)

最后,我們通過(guò)QPixmap()創(chuàng)建并加載了一個(gè)圖片,將其添加到圖形項(xiàng)目QGraphicsPixmapItem()中,并通過(guò)addItem()方法將圖形項(xiàng)目添加到圖形場(chǎng)景管理self.scene中:

png = QtGui.QPixmap()
png.load("logo.png")
item = QtWidgets.QGraphicsPixmapItem(png)
self.scene.addItem(item)

如此,我們就完成了通過(guò)QGraphicsView()類和QGraphicsScene()類在圖形界面(GUI)中展示圖片的功能,運(yùn)行完整的代碼,其顯示出來(lái)的圖形界面程序如下圖所示:

二、幾行代碼射個(gè)門

上面我們通過(guò)兩種不同的方式實(shí)現(xiàn)了圖片在圖形界面中的展示,接下來(lái),我們借助QtCore中的QPropertyAnimation()來(lái)實(shí)現(xiàn)圖片的動(dòng)畫效果。

QPropertyAnimation()類主要依靠操縱對(duì)象的QT屬性來(lái)實(shí)現(xiàn)動(dòng)畫效果,其有幾個(gè)比較主要的方法:

start():用于啟動(dòng)動(dòng)畫;

stop():用于停止動(dòng)畫;

setStartValue():用于設(shè)置動(dòng)畫的起始值;

setEndValue():用于設(shè)置動(dòng)畫的結(jié)束值;

setDuration():用于設(shè)置動(dòng)畫的持續(xù)時(shí)間;

setKeyValueAt():用于在特定時(shí)間創(chuàng)建一個(gè)關(guān)鍵的動(dòng)畫幀動(dòng)作;

setLoopCount():用于設(shè)置動(dòng)畫的循環(huán)次數(shù);

下面我們就使用QPropertyAnimation()類實(shí)現(xiàn)圖片的動(dòng)畫。為了動(dòng)畫的效果比5毛特效要好一點(diǎn),州的先生(公眾號(hào):zmister2016)在阿里的圖標(biāo)庫(kù)iconfont里找了一個(gè)小足球和球門的圖標(biāo),嗯,就像這樣:

然后,我們創(chuàng)建一個(gè)圖形界面,里面包含一個(gè)按鈕、一個(gè)小球和一個(gè)球門的圖片:

# 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("動(dòng)畫使用-zmister.com") # 設(shè)置窗口標(biāo)題
        self.resize(400,200) # 規(guī)定窗口大小
        self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個(gè)widget部件
        self.button = QtWidgets.QPushButton("射門",self.main_widget) # 創(chuàng)建一個(gè)按鈕
        self.button.setGeometry(10,10,60,30) # 設(shè)置按鈕位置
        self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個(gè)文本標(biāo)簽部件用于顯示足球
        self.label.setGeometry(50,80,50,50) # 設(shè)置足球位置
        png = QtGui.QPixmap()  # 創(chuàng)建一個(gè)繪圖類
        png.load("football.png")  # 從png中加載一個(gè)圖片
        self.label.setPixmap(png)  # 設(shè)置文本標(biāo)簽的圖形
        self.label.setScaledContents(True)

        self.qiumen = QtWidgets.QLabel(self.main_widget)  # 創(chuàng)建一個(gè)文本標(biāo)簽部件用于顯示球門
        self.qiumen.setGeometry(345, 75, 50, 50)  # 設(shè)置球門位置
        pngqiumen = QtGui.QPixmap()  # 創(chuàng)建一個(gè)繪圖類
        pngqiumen.load("qiumen.png")  # 從png中加載一個(gè)圖片
        self.qiumen.setPixmap(pngqiumen)  # 設(shè)置文本標(biāo)簽的圖形

        self.setCentralWidget(self.main_widget)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    gui = MainUi()
    gui.show()
    sys.exit(app.exec_())

運(yùn)行上述代碼,我們會(huì)得到一個(gè)如下圖所示的圖形界面:

我們的目的是想讓圖形界面中的小足球通過(guò)按鈕控制,進(jìn)入到球門中。接下來(lái),我們就通過(guò)QPropertyAnimation()類來(lái)實(shí)現(xiàn)這個(gè)效果。

在MainUi()中新建一個(gè)名為shoot()的方法,在其中寫入以下代碼:

self.anim = QtCore.QPropertyAnimation(self.label,b"geometry") # 設(shè)置動(dòng)畫的對(duì)象及其屬性
self.anim.setDuration(2000) # 設(shè)置動(dòng)畫間隔時(shí)間
self.anim.setStartValue(QtCore.QRect(50,80,50,50)) # 設(shè)置動(dòng)畫對(duì)象的起始屬性
self.anim.setEndValue(QtCore.QRect(360, 90, 10, 10)) # 設(shè)置動(dòng)畫對(duì)象的結(jié)束屬性
self.anim.start() # 啟動(dòng)動(dòng)畫

最后,我們?cè)僦v按鈕的點(diǎn)擊信號(hào)綁定到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("動(dòng)畫使用-zmister.com") # 設(shè)置窗口標(biāo)題
        self.resize(400,200) # 規(guī)定窗口大小
        self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個(gè)widget部件
        self.button = QtWidgets.QPushButton("射門",self.main_widget) # 創(chuàng)建一個(gè)按鈕
        self.button.setGeometry(10,10,60,30) # 設(shè)置按鈕位置
        self.button.clicked.connect(self.shoot)
        self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個(gè)文本標(biāo)簽部件用于顯示足球
        self.label.setGeometry(50,80,50,50) # 設(shè)置足球位置
        png = QtGui.QPixmap()  # 創(chuàng)建一個(gè)繪圖類
        png.load("football.png")  # 從png中加載一個(gè)圖片
        self.label.setPixmap(png)  # 設(shè)置文本標(biāo)簽的圖形
        self.label.setScaledContents(True) # 圖片隨文本部件的大小變動(dòng)

        self.qiumen = QtWidgets.QLabel(self.main_widget)  # 創(chuàng)建一個(gè)文本標(biāo)簽部件用于顯示球門
        self.qiumen.setGeometry(345, 75, 50, 50)  # 設(shè)置球門位置
        pngqiumen = QtGui.QPixmap()  # 創(chuàng)建一個(gè)繪圖類
        pngqiumen.load("qiumen.png")  # 從png中加載一個(gè)圖片
        self.qiumen.setPixmap(pngqiumen)  # 設(shè)置文本標(biāo)簽的圖形

        self.setCentralWidget(self.main_widget)

    def shoot(self):
        self.anim = QtCore.QPropertyAnimation(self.label,b"geometry") # 設(shè)置動(dòng)畫的對(duì)象及其屬性
        self.anim.setDuration(2000) # 設(shè)置動(dòng)畫間隔時(shí)間
        self.anim.setStartValue(QtCore.QRect(50,80,50,50)) # 設(shè)置動(dòng)畫對(duì)象的起始屬性
        self.anim.setEndValue(QtCore.QRect(360, 90, 10, 10)) # 設(shè)置動(dòng)畫對(duì)象的結(jié)束屬性
        self.anim.start() # 啟動(dòng)動(dòng)畫

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    gui = MainUi()
    gui.show()
    sys.exit(app.exec_())

運(yùn)行上述代碼,點(diǎn)擊“射門”按鈕,我們將會(huì)得到如下動(dòng)圖所示的動(dòng)畫:

這樣,通過(guò)QPropertyAnimation()的setDuration()方法、setStartValue()方法、setEndValue()方法我們就實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的動(dòng)畫。

三、圓月彎刀繼續(xù)射門

但是上面的射門動(dòng)畫是一條直線將小足球移動(dòng)到了球門之內(nèi),簡(jiǎn)單粗暴欠缺了些許美感,下面,我們讓這個(gè)射門換一種方式,用圓月彎刀的香蕉球?qū)⑿∽闱蛏淙肭蜷T。

還記得上面我們提過(guò)QPropertyAnimation()的setKeyValueAt()這個(gè)用于設(shè)置動(dòng)畫關(guān)鍵幀的方法?,F(xiàn)在我們就將利用它來(lái)實(shí)現(xiàn)足球射門時(shí)的曲線。

與上面的圖形界面的代碼不一樣的是,我們需要繪制一條曲線線條來(lái)作為足球射門時(shí)的路徑。所以我們需要對(duì)上面的圖形界面的代碼進(jìn)行一些修改:

# 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("動(dòng)畫使用-州的先生zmister.com") # 設(shè)置窗口標(biāo)題
        self.resize(400,200) # 規(guī)定窗口大小
        self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個(gè)widget部件
        self.button = QtWidgets.QPushButton("射門",self.main_widget) # 創(chuàng)建一個(gè)按鈕
        self.button.setGeometry(10,10,60,30) # 設(shè)置按鈕位置

        self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個(gè)文本標(biāo)簽部件用于顯示足球
        self.label.setGeometry(50,150,50,50) # 設(shè)置足球位置
        png = QtGui.QPixmap()  # 創(chuàng)建一個(gè)繪圖類
        png.load("football.png")  # 從png中加載一個(gè)圖片
        self.label.setPixmap(png)  # 設(shè)置文本標(biāo)簽的圖形
        self.label.setScaledContents(True) # 圖片隨文本部件的大小變動(dòng)

        self.qiumen = QtWidgets.QLabel(self.main_widget)  # 創(chuàng)建一個(gè)文本標(biāo)簽部件用于顯示球門
        self.qiumen.setGeometry(345, 75, 50, 50)  # 設(shè)置球門位置
        pngqiumen = QtGui.QPixmap()  # 創(chuàng)建一個(gè)繪圖類
        pngqiumen.load("qiumen.png")  # 從png中加載一個(gè)圖片
        self.qiumen.setPixmap(pngqiumen)  # 設(shè)置文本標(biāo)簽的圖形

        self.path = QtGui.QPainterPath() # 實(shí)例化一個(gè)繪制類,用于繪制動(dòng)作
        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) # 在圖形界面上根據(jù)self.path繪制一條線條
        qp.end()
        
if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    gui = MainUi()
    gui.show()
    sys.exit(app.exec_())

在上面的代碼中,與之前的程序代碼有一下不同之處:

我們實(shí)例化創(chuàng)建了一個(gè)QtGui.QPainterPath(),用于進(jìn)行繪制操作。通過(guò)它的moveTo()方法,設(shè)置了繪制的起始點(diǎn),通過(guò)它的cubicTo()方法,設(shè)置的繪制的整個(gè)路徑:

self.path = QtGui.QPainterPath() # 實(shí)例化一個(gè)繪制類,用于繪制動(dòng)作
self.path.moveTo(50, 150)
self.path.cubicTo(50, 150, 50, 20, 370, 90)

接著,我們重寫了窗口的paintEvent()方法,根據(jù)繪制操作的定義,在圖形上繪制一條相應(yīng)的線條:

def paintEvent(self, e):
    qp = QtGui.QPainter()
    qp.begin(self)
    qp.drawPath(self.path) # 在圖形界面上根據(jù)self.path繪制一條線條
    qp.end()

這樣,我們的圖形界面程序呈現(xiàn)出來(lái)的就是如下圖所示的樣子:

圖形上呈現(xiàn)了我們?cè)O(shè)置的足球?qū)⒁\(yùn)動(dòng)的軌跡,接下來(lái),我們通過(guò)QPropertyAnimation()的setKeyValueAt()設(shè)置關(guān)鍵幀的路徑,來(lái)實(shí)現(xiàn)足球曲線射門,具體操作同樣在shoot()方法中進(jìn)行:

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)) # 設(shè)置動(dòng)畫對(duì)象的起始屬性
    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()

最后,同樣將“射門”按鈕的點(diǎn)擊信號(hào)綁定在shoot()方法上。運(yùn)行程序代碼,點(diǎn)擊“射門”按鈕,將會(huì)出現(xiàn)如下動(dòng)圖所示的動(dòng)畫效果:

為了更加的美觀,其實(shí)可以將重寫的paintEvent()去掉,在這里為了演示路徑,就沒(méi)有去除。

在PyQt5中使用動(dòng)畫是不是很簡(jiǎn)單?有問(wèn)題歡迎留言討論。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/42287.html

相關(guān)文章

  • 世界杯押注還得看技術(shù)流,這個(gè)預(yù)測(cè)AI把賠率也算上了

    摘要:世界杯小組賽將收官,你還依然信嗎冷門頻出,黑馬擊敗豪強(qiáng)。以本屆世界杯開(kāi)幕戰(zhàn)俄羅斯對(duì)陣沙特阿拉伯的比賽為例,兩隊(duì)上次交手是在年的一場(chǎng)友誼賽,距今已經(jīng)年。然后進(jìn)入第二步,預(yù)測(cè)回報(bào)率導(dǎo)向。在足球領(lǐng)域,這個(gè)回報(bào)率已非常不俗。 世界杯小組賽將收官,你還依然信AI嗎?冷門頻出,黑馬擊敗豪強(qiáng)。不少AI模型始料未及。到底還能不能愉快找到科學(xué)規(guī)律?或者說(shuō)足球比賽乃至其他競(jìng)技體育賽事,數(shù)據(jù)科學(xué)家在AI加持下,究...

    walterrwu 評(píng)論0 收藏0
  • 這里有一個(gè)機(jī)器學(xué)習(xí)模型,它知道2.2億歐元內(nèi)馬爾值不值得買

    摘要:也就是說(shuō),這個(gè)機(jī)器學(xué)習(xí)模型,現(xiàn)在還只能當(dāng)做一種參考,還不能將場(chǎng)外號(hào)召力也計(jì)入工資體系中。不過(guò)研究者稱,無(wú)論是足球迷還是非足球迷,這個(gè)機(jī)器學(xué)習(xí)模型,都能為未來(lái)商品定價(jià)提供參考。 內(nèi)馬爾2.2億歐元轉(zhuǎn)換大巴黎阿森納主帥溫格在位20載,什么樣優(yōu)秀的球員沒(méi)見(jiàn)過(guò),但現(xiàn)今他也是越來(lái)越看不懂轉(zhuǎn)會(huì)市場(chǎng)了。溫格感嘆:不是阿森納不買人,實(shí)在是現(xiàn)今市場(chǎng)上的球員貴得離譜。此言其實(shí)不虛。120萬(wàn)英鎊的坎通納幫助弗格森...

    LeanCloud 評(píng)論0 收藏0
  • 姆巴佩獨(dú)造三球一戰(zhàn)成名 阿里云打破世界杯流量紀(jì)錄

    摘要:這個(gè)周末舉行的俄羅斯世界杯決賽可謂精彩紛呈,高盧雄雞和潘帕斯雄鷹上演進(jìn)球大戰(zhàn),姆巴佩一人獨(dú)造三粒進(jìn)球一戰(zhàn)成名,法國(guó)隊(duì)比送阿根廷回家,梅西再度飲恨而歸,另一邊葡萄牙比不敵烏拉圭,梅西與羅兩大超巨止步八強(qiáng)。 摘要: 這個(gè)周末舉行的俄羅斯世界杯1/8決賽可謂精彩紛呈,高盧雄雞和潘帕斯雄鷹上演進(jìn)球大戰(zhàn),姆巴佩一人獨(dú)造三粒進(jìn)球一戰(zhàn)成名,法國(guó)隊(duì)4比3送阿根廷回家,梅西再度飲恨而歸,另一邊葡萄牙1比...

    aaron 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<