摘要:作為一個全面的桌面應(yīng)用程序開發(fā)包,其自然提供了對圖像的動畫支持。本篇文章中,就來簡單地在中使用動畫功能實現(xiàn)一個足球射門的動畫效果。還記得上面我們提過的這個用于設(shè)置動畫關(guān)鍵幀的方法。在中使用動畫是不是很簡單有問題歡迎留言討論。
QT作為一個全面的桌面應(yīng)用程序開發(fā)包,其自然提供了對圖像的動畫支持。本篇文章中,就來簡單地在PYQt5中使用Animation動畫功能實現(xiàn)一個足球射門的動畫效果。
本篇將會依次完成以下功能:
在GUI界面中顯示一個圖片(用一個足球做演示);
點擊按鈕實現(xiàn)足球的直線射門動畫;
點擊按鈕實現(xiàn)足球的曲線射門動畫;
本文首發(fā)州的先生博客:Python GUI教程(十五):在PyQt5中使用動畫,轉(zhuǎn)載請注明出處一、在圖形界面顯示圖片的兩種方法
一般情況下,想要在GUI中顯示圖片,我們會通過:
實例化一個QLable()部件;
實例化一個QPixmap()圖形類;
通過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("動畫使用-zmister.com") # 設(shè)置窗口標題 self.resize(400,200) # 規(guī)定窗口大小 self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個widget部件 self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個文本標簽部件 png = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 png.load("logo.png") # 從pngz中加載一個圖片 self.label.setPixmap(png) # 設(shè)置文本標簽的圖形 self.setCentralWidget(self.main_widget) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) gui = MainUi() gui.show() sys.exit(app.exec_())
運行上述代碼,我們將會得到如下所示的圖形界面:
但是這種方法沒有辦法實現(xiàn)對圖片更多的控制。為了更好地對圖形界面中的圖片進行控制和管理,我們還需要使用到其他的類,比如QtWidgets中的QGraphicsScene類,QGraphicsScene提供了一個場景,用于對2D圖形進行管理。同時,為了展示QGraphicsScene中的內(nèi)容,我們還需要使用到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") # 設(shè)置窗口標題 self.resize(400,200) # 規(guī)定窗口大小 self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個widget部件 self.grapview = QtWidgets.QGraphicsView(self.main_widget) # 創(chuàng)建一個圖形視圖,繼承自main_widget self.grapview.setGeometry(QtCore.QRect(10, 10, 380, 180)) # 設(shè)置圖形視圖的矩形區(qū)域 self.scene = QtWidgets.QGraphicsScene() # 創(chuàng)建一個圖形管理場景 self.grapview.setScene(self.scene) png = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 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_())
在這里面,基礎(chǔ)的窗口代碼與之前的代碼類似,有區(qū)別且最核心的為以下幾行代碼。
首先,我們實例化創(chuàng)建了一個用于展示圖形場景的圖形視圖QGraphicsView(),將它繼承自self.main_widget主窗口部件:
self.grapview = QtWidgets.QGraphicsView(self.main_widget)
然后,我們實例化創(chuàng)建了一個圖形場景管理類QGraphicsScene(),并通過setScene()方法將圖形視圖self.grapview的圖形場景設(shè)置為剛剛實例化創(chuàng)建的QGraphicsScene():
self.scene = QtWidgets.QGraphicsScene() self.grapview.setScene(self.scene)
最后,我們通過QPixmap()創(chuàng)建并加載了一個圖片,將其添加到圖形項目QGraphicsPixmapItem()中,并通過addItem()方法將圖形項目添加到圖形場景管理self.scene中:
png = QtGui.QPixmap() png.load("logo.png") item = QtWidgets.QGraphicsPixmapItem(png) self.scene.addItem(item)
如此,我們就完成了通過QGraphicsView()類和QGraphicsScene()類在圖形界面(GUI)中展示圖片的功能,運行完整的代碼,其顯示出來的圖形界面程序如下圖所示:
二、幾行代碼射個門上面我們通過兩種不同的方式實現(xiàn)了圖片在圖形界面中的展示,接下來,我們借助QtCore中的QPropertyAnimation()來實現(xiàn)圖片的動畫效果。
QPropertyAnimation()類主要依靠操縱對象的QT屬性來實現(xiàn)動畫效果,其有幾個比較主要的方法:
start():用于啟動動畫;
stop():用于停止動畫;
setStartValue():用于設(shè)置動畫的起始值;
setEndValue():用于設(shè)置動畫的結(jié)束值;
setDuration():用于設(shè)置動畫的持續(xù)時間;
setKeyValueAt():用于在特定時間創(chuàng)建一個關(guān)鍵的動畫幀動作;
setLoopCount():用于設(shè)置動畫的循環(huán)次數(shù);
下面我們就使用QPropertyAnimation()類實現(xiàn)圖片的動畫。為了動畫的效果比5毛特效要好一點,州的先生(公眾號:zmister2016)在阿里的圖標庫iconfont里找了一個小足球和球門的圖標,嗯,就像這樣:
然后,我們創(chuàng)建一個圖形界面,里面包含一個按鈕、一個小球和一個球門的圖片:
# 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") # 設(shè)置窗口標題 self.resize(400,200) # 規(guī)定窗口大小 self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個widget部件 self.button = QtWidgets.QPushButton("射門",self.main_widget) # 創(chuàng)建一個按鈕 self.button.setGeometry(10,10,60,30) # 設(shè)置按鈕位置 self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個文本標簽部件用于顯示足球 self.label.setGeometry(50,80,50,50) # 設(shè)置足球位置 png = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 png.load("football.png") # 從png中加載一個圖片 self.label.setPixmap(png) # 設(shè)置文本標簽的圖形 self.label.setScaledContents(True) self.qiumen = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個文本標簽部件用于顯示球門 self.qiumen.setGeometry(345, 75, 50, 50) # 設(shè)置球門位置 pngqiumen = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 pngqiumen.load("qiumen.png") # 從png中加載一個圖片 self.qiumen.setPixmap(pngqiumen) # 設(shè)置文本標簽的圖形 self.setCentralWidget(self.main_widget) if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) gui = MainUi() gui.show() sys.exit(app.exec_())
運行上述代碼,我們會得到一個如下圖所示的圖形界面:
我們的目的是想讓圖形界面中的小足球通過按鈕控制,進入到球門中。接下來,我們就通過QPropertyAnimation()類來實現(xiàn)這個效果。
在MainUi()中新建一個名為shoot()的方法,在其中寫入以下代碼:
self.anim = QtCore.QPropertyAnimation(self.label,b"geometry") # 設(shè)置動畫的對象及其屬性 self.anim.setDuration(2000) # 設(shè)置動畫間隔時間 self.anim.setStartValue(QtCore.QRect(50,80,50,50)) # 設(shè)置動畫對象的起始屬性 self.anim.setEndValue(QtCore.QRect(360, 90, 10, 10)) # 設(shè)置動畫對象的結(jié)束屬性 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") # 設(shè)置窗口標題 self.resize(400,200) # 規(guī)定窗口大小 self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個widget部件 self.button = QtWidgets.QPushButton("射門",self.main_widget) # 創(chuàng)建一個按鈕 self.button.setGeometry(10,10,60,30) # 設(shè)置按鈕位置 self.button.clicked.connect(self.shoot) self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個文本標簽部件用于顯示足球 self.label.setGeometry(50,80,50,50) # 設(shè)置足球位置 png = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 png.load("football.png") # 從png中加載一個圖片 self.label.setPixmap(png) # 設(shè)置文本標簽的圖形 self.label.setScaledContents(True) # 圖片隨文本部件的大小變動 self.qiumen = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個文本標簽部件用于顯示球門 self.qiumen.setGeometry(345, 75, 50, 50) # 設(shè)置球門位置 pngqiumen = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 pngqiumen.load("qiumen.png") # 從png中加載一個圖片 self.qiumen.setPixmap(pngqiumen) # 設(shè)置文本標簽的圖形 self.setCentralWidget(self.main_widget) def shoot(self): self.anim = QtCore.QPropertyAnimation(self.label,b"geometry") # 設(shè)置動畫的對象及其屬性 self.anim.setDuration(2000) # 設(shè)置動畫間隔時間 self.anim.setStartValue(QtCore.QRect(50,80,50,50)) # 設(shè)置動畫對象的起始屬性 self.anim.setEndValue(QtCore.QRect(360, 90, 10, 10)) # 設(shè)置動畫對象的結(jié)束屬性 self.anim.start() # 啟動動畫 if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) gui = MainUi() gui.show() sys.exit(app.exec_())
運行上述代碼,點擊“射門”按鈕,我們將會得到如下動圖所示的動畫:
這樣,通過QPropertyAnimation()的setDuration()方法、setStartValue()方法、setEndValue()方法我們就實現(xiàn)了一個簡單的動畫。
三、圓月彎刀繼續(xù)射門但是上面的射門動畫是一條直線將小足球移動到了球門之內(nèi),簡單粗暴欠缺了些許美感,下面,我們讓這個射門換一種方式,用圓月彎刀的香蕉球?qū)⑿∽闱蛏淙肭蜷T。
還記得上面我們提過QPropertyAnimation()的setKeyValueAt()這個用于設(shè)置動畫關(guān)鍵幀的方法。現(xiàn)在我們就將利用它來實現(xià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("動畫使用-州的先生zmister.com") # 設(shè)置窗口標題 self.resize(400,200) # 規(guī)定窗口大小 self.main_widget = QtWidgets.QWidget() # 創(chuàng)建一個widget部件 self.button = QtWidgets.QPushButton("射門",self.main_widget) # 創(chuàng)建一個按鈕 self.button.setGeometry(10,10,60,30) # 設(shè)置按鈕位置 self.label = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個文本標簽部件用于顯示足球 self.label.setGeometry(50,150,50,50) # 設(shè)置足球位置 png = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 png.load("football.png") # 從png中加載一個圖片 self.label.setPixmap(png) # 設(shè)置文本標簽的圖形 self.label.setScaledContents(True) # 圖片隨文本部件的大小變動 self.qiumen = QtWidgets.QLabel(self.main_widget) # 創(chuàng)建一個文本標簽部件用于顯示球門 self.qiumen.setGeometry(345, 75, 50, 50) # 設(shè)置球門位置 pngqiumen = QtGui.QPixmap() # 創(chuàng)建一個繪圖類 pngqiumen.load("qiumen.png") # 從png中加載一個圖片 self.qiumen.setPixmap(pngqiumen) # 設(shè)置文本標簽的圖形 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) # 在圖形界面上根據(jù)self.path繪制一條線條 qp.end() if __name__ == "__main__": app = QtWidgets.QApplication(sys.argv) gui = MainUi() gui.show() sys.exit(app.exec_())
在上面的代碼中,與之前的程序代碼有一下不同之處:
我們實例化創(chuàng)建了一個QtGui.QPainterPath(),用于進行繪制操作。通過它的moveTo()方法,設(shè)置了繪制的起始點,通過它的cubicTo()方法,設(shè)置的繪制的整個路徑:
self.path = QtGui.QPainterPath() # 實例化一個繪制類,用于繪制動作 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)出來的就是如下圖所示的樣子:
圖形上呈現(xiàn)了我們設(shè)置的足球?qū)⒁\動的軌跡,接下來,我們通過QPropertyAnimation()的setKeyValueAt()設(shè)置關(guān)鍵幀的路徑,來實現(xiàn)足球曲線射門,具體操作同樣在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)) # 設(shè)置動畫對象的起始屬性 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()方法上。運行程序代碼,點擊“射門”按鈕,將會出現(xiàn)如下動圖所示的動畫效果:
為了更加的美觀,其實可以將重寫的paintEvent()去掉,在這里為了演示路徑,就沒有去除。
在PyQt5中使用動畫是不是很簡單?有問題歡迎留言討論。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/42287.html
摘要:世界杯小組賽將收官,你還依然信嗎冷門頻出,黑馬擊敗豪強。以本屆世界杯開幕戰(zhàn)俄羅斯對陣沙特阿拉伯的比賽為例,兩隊上次交手是在年的一場友誼賽,距今已經(jīng)年。然后進入第二步,預(yù)測回報率導(dǎo)向。在足球領(lǐng)域,這個回報率已非常不俗。 世界杯小組賽將收官,你還依然信AI嗎?冷門頻出,黑馬擊敗豪強。不少AI模型始料未及。到底還能不能愉快找到科學規(guī)律?或者說足球比賽乃至其他競技體育賽事,數(shù)據(jù)科學家在AI加持下,究...
摘要:也就是說,這個機器學習模型,現(xiàn)在還只能當做一種參考,還不能將場外號召力也計入工資體系中。不過研究者稱,無論是足球迷還是非足球迷,這個機器學習模型,都能為未來商品定價提供參考。 內(nèi)馬爾2.2億歐元轉(zhuǎn)換大巴黎阿森納主帥溫格在位20載,什么樣優(yōu)秀的球員沒見過,但現(xiàn)今他也是越來越看不懂轉(zhuǎn)會市場了。溫格感嘆:不是阿森納不買人,實在是現(xiàn)今市場上的球員貴得離譜。此言其實不虛。120萬英鎊的坎通納幫助弗格森...
摘要:這個周末舉行的俄羅斯世界杯決賽可謂精彩紛呈,高盧雄雞和潘帕斯雄鷹上演進球大戰(zhàn),姆巴佩一人獨造三粒進球一戰(zhàn)成名,法國隊比送阿根廷回家,梅西再度飲恨而歸,另一邊葡萄牙比不敵烏拉圭,梅西與羅兩大超巨止步八強。 摘要: 這個周末舉行的俄羅斯世界杯1/8決賽可謂精彩紛呈,高盧雄雞和潘帕斯雄鷹上演進球大戰(zhàn),姆巴佩一人獨造三粒進球一戰(zhàn)成名,法國隊4比3送阿根廷回家,梅西再度飲恨而歸,另一邊葡萄牙1比...
閱讀 1758·2021-09-27 14:02
閱讀 3148·2021-09-27 13:36
閱讀 1052·2019-08-30 12:46
閱讀 1841·2019-08-30 10:51
閱讀 3578·2019-08-29 17:02
閱讀 946·2019-08-29 16:38
閱讀 1853·2019-08-29 16:37
閱讀 3023·2019-08-26 10:32