1. 程式人生 > >Python-Tkinter-屏保

Python-Tkinter-屏保

lambda表達式 port 運動 create 位置 個數 elf 顏色 over

- 屏保可以自己啟動,也可以手動啟動 (這裏使用手動啟動)
- 一旦移動鼠標後,或者其他的引發事件,則停止
- 如果屏保是一個畫布的話,則沒有畫框
- 圖像的動作是隨機的,具有隨機性,可能包括顏色,大小,個數,運動方向等
- 整體構成:
  - 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-屏保