程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

Python動畫制作:90秒倒計時圓形進度條效果

編輯:Python

今天單獨講解一下使用python自帶的tkinter模塊,如何做出下圖這種倒計時的效果。

我們使用tkinter模塊裡的Canvas畫布組件來完成這個倒計時的制作。


拆解最終完成的圖形,可以看到,除了按鈕用來作為啟動倒計時,用來表示倒計時的圓形進度條可以拆解為下面四個組件:

1. 黃色的外圓框(一個填充為空白,邊框為黃色的圓)

2. 紅色的扇形(進度條的核心,隨著倒計時而改變扇形的角度)

3. 黃色的同心圓(用來遮住扇形的內部,顯示出環繞進度條的效果)

4. 中間的文字(每秒倒計時,隨著扇形一起變化)

所以,其實並不難,我們來分別實現:

圓形

Canvas繪制圓形的函數是create_oval。所以繪制黃色的外圓框,和裡面黃色的小同心圓,都可以使用這個函數。具體方法是:

# 繪制黃色的外圓框
cv.create_oval(100,50,350,300,outline='yellow')
# 繪制黃色的小同心圓
cv.create_oval(150,100,300,250,fill='yellow',outline='yellow')

 參數也比較簡單,前面四個數字分別代表了這個圓所占的正方形的左上角(x1和y1)和右下角(x2和y2)的坐標。當然這個正方形只是表示位置,並不會出現正方形的邊框或內容。

後面跟著的fill表示填充的顏色,如果不寫這個參數,就表示是一個空心的圓。outline表示外邊框的顏色,我們這裡都使用了黃色yellow。此外還有其他參數,比如width,可以表示外邊框的厚度,默認是1,我們這裡就沒有特意指定了。

扇形

接著繪制扇形。Canvas繪制扇形(弧形)的函數是create_arc。比如下面這條代碼就畫了上面例子中的一個四分之三圓形面積的扇形。

cv.create_arc(100,50,350,300,start=90,extent=270,fill="red",outline='yellow')

前面四個數字和繪制圓形的一樣,表示扇形所占正方形位置的左上角和右下角的坐標。fill和outline的參數也和圓形一樣,表示填充的顏色和外邊框的顏色。比較重要的參數是start和extent。

start參數表示扇形的起始角度,extent表示逆時針開始,繪制到多少角度。所以,這裡start=90,extent=270,就表示弧形的一邊是垂直的(90度起始角度),另一邊是向右水平的(逆時針旋轉270度)

數字

而最後的文字(數字)可以使用Canvas的create_text函數:

cv.create_text(225,175,text='90',font =('微軟雅黑',64,'bold'),fill='red')

代碼中前面兩個數字表示文字中心的橫縱坐標,這也方便了我們,不管文字內容如何變化,可以始終居中。參數text表示顯示的內容,fill表示文字的顏色,font則表示文字的字體、大小、粗細等屬性。


代碼邏輯

組件就這麼多,實現的原理也很簡單:

  1. 創建一個按鈕,使用回調函數countdown。
  2. 回調函數中隨著變化的角度繪制扇形並更新文字,360度按照90秒倒計時,那麼每秒鐘減少4度正好,也就是說,每秒鐘繪制一個減少4度的扇形。
  3. 使用after方法設定countdown函數每一秒鐘執行一次(類似上篇文章的擲骰子)。
  4. 如果數字和扇形的角度減少到0,則停止倒計時。

雖然很簡單,但是其實這裡面也有幾個小坑:

  1. 一開始還沒有倒計時的時候,扇形的位置應該是個圓形,也就是說,扇形的角度應該是360度。但是遺憾的是,如果把create_arc函數裡的參數extent設置為360,我們得不到一個圓形,所以在開始的時候,我們要再扇形的位置另外繪制一個圓形。
  2. 每秒鐘繪制新的扇形之前,必須先把老的扇形圖形給刪去,不然無法顯示出新的圖形。
  3. 繪制圖形的位置也很重要,雖然理論上,需要重新繪制的只有變化的扇形和中間一直減少的數字,但實際上那個小同心圓也要重新繪制,道理和上一條一樣,如果不繪制,就會被新繪制的扇形所擋住。
  4. 按鈕按下的時候,應該在1秒後才開始變成89,外面的扇形也隨之變成356度(360-4),換句話說,這個變化不是馬上發生的。而如果放在一個可重復執行的函數裡,就需要加一個判斷:第一秒的時候什麼都不做。
  5. 按鈕按下以後,按鈕的狀態應該就失效了(DISABLED),不然,如果可以一直點,倒計時將變得混亂。而在倒計時結束後,按鈕的狀態才回復正常(NORMAL),從而可以開始一個新的倒計時。

代碼實現

from tkinter import *
import tkinter.messagebox as tm
count=90
angle=360
def countdown():
global angle,count,cv_arc
btn['state']=DISABLED
if angle==360:
angle -= 4
else:
cv.delete(cv_arc)
cv_arc=cv.create_arc(100,50,350,300,start=90,extent=angle,fill="red",outline='yellow')
angle -= 4
count-=1
cv.create_oval(150,100,300,250,fill='yellow',outline='yellow')
cv.create_text(225,175,text=count,font =('微軟雅黑',64,'bold'),fill='red')
if count==0:
tm.showinfo(message='倒計時結束!')
angle = 360
cv.delete(cv_arc)
cv_arc=cv.create_oval(100,50,350,300,fill='red',outline='yellow')
count=90
cv.create_oval(150,100,300,250,fill='yellow',outline='yellow')
cv.create_text(225,175,text=count,font =('微軟雅黑',64,'bold'),fill='red')
btn['state']=NORMAL
else:
root.after(1000,countdown)
root = Tk()
root.geometry('450x450')
root.resizable(0,0)
root.title('倒計時')
cv = Canvas(root,width=450,height=450,bg='white')
btn = Button(root,text='開始',width=5,command=countdown)
cv_btn = cv.create_window(225,350,window=btn)
cv.create_oval(100,50,350,300,outline='yellow')
cv_arc=cv.create_oval(100,50,350,300,fill='red',outline='yellow')
cv.create_oval(150,100,300,250,fill='yellow',outline='yellow')
cv.create_text(225,175,text=90,font =('微軟雅黑',64,'bold'),fill='red')
cv.pack()
root.mainloop()

總結與思考

當然,倒計時90秒只是一個例子,隨你願意,可以倒計時任意時間。但要注意的是,每一秒扇形的角度變化也要隨著倒計時數字的不同而調整。比如倒計時90秒時,每秒鐘就減少360/90=4度,如果倒計時60秒,則每秒鐘減少360/60=6度,倒計時120秒則是360/120=3度,以此類推。

當然,顏色和位置、大小都可以變化(問哥也覺得大盤的番茄炒蛋有點嚇人,但是主旋律,你懂得:D),只要注意前後順序,不要被新繪制的扇形擋住就好。

最後,大家也可以思考一下,如果想要倒計時的數字和外面的扇形並不同時變化,該如何實現。就是類似下面這種效果,扇形的變化更加平滑:

其實並不難,只要在現有的代碼上做一個小變化即可,大家開動腦筋思考一下吧。:D


  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved