Python-Tkinter-屏保

- 屏保可以自己启动,也可以手动启动 (这里使用手动启动)
- 一旦移动鼠标后,或者其他的引发事件,则停止
- 如果屏保是一个画布的话,则没有画框
- 图像的动作是随机的,具有随机性,可能包括颜色,大小,个数,运动方向等
- 整体构成:
  - 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()

猜你喜欢

转载自www.cnblogs.com/qiuxirufeng/p/9108490.html