標籤:原來 停止 += 手動 width move oci 地方 UI
- 屏保可以自己啟動,也可以手動啟動 (這裡使用手動啟動)
- 一旦移動滑鼠後,或者其他的引發事件,則停止
- 如果屏保是一個畫布的話,則沒有畫框
- 映像的動作是隨機的,具有隨機性,可能包括顏色,大小,個數,運動方向等
- 整體構成:
- ScreenSaver:
- 需要一個Canvas, 大小與螢幕一致,沒有邊框
- Ball
- 顏色,大小,個數,運動方向等隨機
- 球能動,通過調用
1 __author__ = "qiuxirufeng" 2 3 import random 4 import tkinter 5 6 7 class RandromBall(): 8 ‘‘‘ 9 定義運動的球的類 10 ‘‘‘ 11 12 def __init__(self, canvas, scrnwidth, scrnheight): 13 ‘‘‘ 14 canvas:畫布,所有的內容都應該在畫布上呈現處理,此處通過此變數傳入 15 scrnwidth/scrnheight:螢幕的尺寸,寬和高 16 ‘‘‘ 17 # 初始化畫布 18 self.canvas = canvas 19 20 # 球出現的初始位置隨機,此處位置表示球的圓心 21 # xpos、ypos表示出現位置的座標 22 self.xpos = random.randint(10, int(scrnwidth) - 20) 23 self.ypos = random.randint(10, int(scrnheight) - 20) 24 25 # 定義球運動的速度 26 # 類比運動:不斷地擦除原來的畫,在一個新的地方再重新繪製 27 # 此處xvelocity類比x軸方向運動 28 self.xvelocity = random.randint(4, 20) 29 # 同理yvelocity類比的是y軸方向運動 30 self.yvelocity = random.randint(4, 20) 31 32 # 定義螢幕的大小 33 self.scrnwidth = scrnwidth 34 self.scrnheight = scrnheight 35 36 # 球的大小隨機 37 # 此處球的大小用半徑表示 38 self.radius = random.randint(20, 120) 39 40 # 定義顏色 41 # RGB標記法:三個數字,每個數位值是0-255之間,表示紅綠藍三個顏色的大小 42 # 在某些系統中,也可以直接用英文單詞表示,例如red, green 43 # 此處採用RGB標記法,用lambda運算式,求RGB三個隨機值的匿名函數 44 c = lambda: random.randint(0, 255) 45 self.color = "#%02x%02x%02x" % (c(), c(), c()) 46 47 def create_ball(self): 48 ‘‘‘ 49 用建構函式定義的變數值,zaicanvas上畫一個球 50 ‘‘‘ 51 52 # tkinter沒有畫圓形的函數,只有畫橢圓的函數,畫橢圓需要定義兩個座標 53 # 在一個矩形內畫橢圓,只需要定義矩形的左上方和右下角即可 54 # 求兩個座標的方法是,已知圓心的座標,則圓心座標減去半徑能求出左上方座標,加上半徑能求出右下角座標 55 x1 = self.xpos - self.radius 56 y1 = self.ypos - self.radius 57 x2 = self.xpos + self.radius 58 y2 = self.ypos + self.radius 59 60 # 在有兩個對角座標的前提下,可以進行畫圓操作 61 # fill表示填充顏色 62 # outline是圓的外圍邊框顏色 63 self.item = self.canvas.create_oval(x1, y1, x2, y2, fill=self.color, outline=self.color) 64 65 def move_ball(self): 66 # 移動球的時候,需要控制球的移動方向 67 # 每次移動後,球都有一個新的座標 68 self.xpos += self.xvelocity 69 self.ypos += self.yvelocity 70 71 # 以下判斷球是否會撞牆 72 if self.xpos + self.radius >= self.scrnwidth or self.xpos - self.radius <= 0: 73 # 撞到了左邊右邊的牆,球朝著相反方向,x為負 74 self.xvelocity = -self.xvelocity 75 # 或者用下一行代碼,給x加一個負號 76 # self.xvelocity *= -1 77 # 同理,撞到上下邊的牆 78 # if self.ypos >= self.scrnheight - self.radius: 79 # self.yvelocity = - self.yvelocity 80 # 81 # if self.ypos <= self.radius: 82 # self.yvelocity = abs(self.yvelocity) 83 # 上下邊的牆也可以用以下兩行代碼代替 84 if self.ypos + self.radius >= self.scrnheight or self.ypos - self.radius <= 0: 85 self.yvelocity = - self.yvelocity 86 87 # 在畫布上挪動圖畫 88 self.canvas.move(self.item, self.xvelocity, self.yvelocity) 89 90 91 class ScreenSaver(): 92 ‘‘‘ 93 定義屏保的類 94 可以被啟動 95 ‘‘‘ 96 # 屏保用來裝隨機產生的球 97 balls = [] 98 99 def __init__(self):100 # 每次啟動球的數量隨機,範圍在6到50之內101 self.num_balls = random.randint(6, 50)102 103 self.root = tkinter.Tk()104 # 取消邊框105 self.root.overrideredirect(1)106 107 # 任何滑鼠移動都需要取消屏保108 self.root.bind(‘<Motion>‘, self.myquit)109 110 # 得到螢幕的大小規格111 w, h = self.root.winfo_screenwidth(), self.root.winfo_screenheight()112 113 # 建立畫布,包括畫布的歸屬,規格114 self.canvas = tkinter.Canvas(self.root, width=w, height=h)115 self.canvas.pack()116 117 # 在畫布上畫球118 for i in range(self.num_balls):119 ball = RandromBall(self.canvas, scrnwidth=w, scrnheight=h)120 ball.create_ball()121 self.balls.append(ball)122 123 self.run_screen_saver()124 self.root.mainloop()125 126 def run_screen_saver(self):127 for ball in self.balls:128 ball.move_ball()129 130 # after是80毫秒後啟動一個函數,需要啟動的函數是第二個參數131 self.canvas.after(80, self.run_screen_saver)132 133 def myquit(self, event):134 self.root.destroy()135 136 if __name__ == ‘__main__‘:137 ScreenSaver()
Python-Tkinter-屏保