继续写这个专题,欢迎持续关注,相信你一定会有所收获。
今天是在上述三篇的基础上,进一步提高,实现:
python使用tkinter实现透明窗体上绘制美丽的飞机
飞机,即图片,跟小球最大的区别在于:其实2D图形,需要考虑的东东更多,譬如旋转的角度。因此在实现之初,需要研究如何使图片旋转。
实现飞机自动旋转
def move_plane(canvas,root):
global angle,canvas_obj,kk,image,tkimage
# kk =
tkimage = ImageTk.PhotoImage(image.rotate(-angle))
# del kk
# kk.append(tkimage)
if canvas_obj is not None:
canvas.delete(canvas_obj)
canvas_obj = canvas.create_image(250, 250, image=tkimage)
angle += 1
angle %= 360
print(angle)
canvas.after(10, move_plane, canvas, tk)
from PIL import ImageTk,Image
import tkinter as tk
root = tk.Tk()
root.geometry('600x500+300+100')
root.title('有趣的透明窗体-开篇了!!!')
canvas = tk.Canvas(root)
canvas.pack(fill=tk.BOTH, expand=tk.Y)
root.update()
angle = 0
canvas_obj = None
image = Image.open('plane.png')
tkimage = None
def move_plane(canvas,root):
global angle,canvas_obj,kk,image,tkimage
# kk =
tkimage = ImageTk.PhotoImage(image.rotate(-angle))
# del kk
# kk.append(tkimage)
if canvas_obj is not None:
canvas.delete(canvas_obj)
canvas_obj = canvas.create_image(250, 250, image=tkimage)
angle += 1
angle %= 360
print(angle)
canvas.after(10, move_plane, canvas, tk)
move_plane(canvas,root)
root.mainloop()
def __init__(self, canvas,root):
self.canvas = canvas
self.root = root
self.image = Image.open('plane.png')
def create_ball(self):
# tkinter绘图采用屏幕坐标系,原点在左上角,x从左往右递增,y从上往下递增
# 随机产生表示当前球的大小,也就是半径长度
self.radius = randint(2, 10)
self.scrnwidth = int(self.root.winfo_width())
self.scrnheight = int(self.root.winfo_height())
# 在绘图区域内,随机产生当前球的圆心的x坐标和y坐标,用于制定出现的位置
self.xpos = randint(self.radius, int(self.root.winfo_width())-self.radius)
self.ypos = randint(self.radius, int(self.root.winfo_height())-self.radius)
# 在绘图区域内,随机产生当前球的x坐标和y坐标的向量
# 在数学中,几何向量(也称矢量),指具有大小和方向的量
# 这里我们可以用来表示球的速度
self.xvelocity = randint(2, 6)
self.yvelocity = randint(2, 6)
self.angle = math.atan2(self.yvelocity,self.xvelocity)
self.fangle = math.degrees(self.angle)+90
self.tkimage = ImageTk.PhotoImage(self.image.rotate(-self.fangle))
self.canvas_obj = canvas.create_image(self.xpos, self.ypos, image=self.tkimage)
# 通过lambda表达式创建函数对象r,每次调用r()都会产生0~255之间的数字
r = lambda: randint(0, 255)
# 三次调用的数字取前两位,用十六进制数方式存储到self.color里,作为球的颜色
# RRGGBB,前2是红色,中2是绿色,后2是蓝色,最小是0,最大是F
# 如全黑#000000 全白#FFFFFF 全红#FF0000
self.color = "#%02x%02x%02x" % (r(), r(), r())
# canvas.create_oval可以绘制一个圆
# 但是需要传入圆的左、上、右、下四个坐标
# 所以我们先产生4个坐标,通过这个四个坐标,绘制圆的大小
# 左坐标=x坐标-半径
x1 = self.xpos - self.radius
# 上坐标=y坐标-半径
y1 = self.ypos - self.radius
# 右坐标=x坐标+半径
x2 = self.xpos + self.radius
# 下坐标=y坐标+半径
y2 = self.ypos + self.radius
# 通过canvas.create_oval()方法绘出整个圆,填充色和轮廓色分别是self.color生成的颜色
# self.canvas.delete('ball')
# self.ball = self.canvas.create_oval(x1, y1, x2, y2, fill=self.color, outline=self.color,tag='ball')
# canvas.addtag_all('t5')
print(x1,y1,x2,y2,self.color,self.radius,self.angle,self.fangle)
self.angle = math.atan2(self.yvelocity,self.xvelocity)
self.fangle = math.degrees(self.angle)+90
self.tkimage = ImageTk.PhotoImage(self.image.rotate(-self.fangle))
self.canvas_obj = canvas.create_image(self.xpos, self.ypos, image=self.tkimage)
实现飞机旋转和图像更新
def move_ball(self):
# 进行相应的移动,如果坐标超过屏幕边缘则向相反方向移动
# 让球的x坐标和y坐标,按照向量的大小进行增加,表示球的运行,向下和向右
print(self.color,self.radius,self.angle,self.fangle)
self.scrnwidth = int(self.root.winfo_width())
self.scrnheight = int(self.root.winfo_height())
self.xpos += self.xvelocity
self.ypos += self.yvelocity
# 如果球的y坐标大于等于屏幕高度和球的半径的差,则调整球的运行y轴方向朝上
if self.ypos >= self.scrnheight - self.radius:
self.yvelocity = -self.yvelocity
self.angle = math.atan2(self.yvelocity, self.xvelocity)
self.fangle = math.degrees(self.angle) + 90
self.tkimage = ImageTk.PhotoImage(self.image.rotate(-self.fangle))
self.canvas_obj = canvas.create_image(self.xpos, self.ypos, image=self.tkimage)
# 如果球的y坐标小于等于屏幕高度和球的半径的差,则调整球的y轴运行方向朝下
if self.ypos <= self.radius:
self.yvelocity = abs(self.yvelocity)
self.angle = math.atan2(self.yvelocity, self.xvelocity)
self.fangle = math.degrees(self.angle) + 90
self.tkimage = ImageTk.PhotoImage(self.image.rotate(-self.fangle))
self.canvas_obj = canvas.create_image(self.xpos, self.ypos, image=self.tkimage)
# 如果球的x坐标大于等于屏幕宽度和球的半径差,则调整球的运行x轴方向朝左
if self.xpos >= self.scrnwidth - self.radius:
self.xvelocity = -self.xvelocity
self.angle = math.atan2(self.yvelocity, self.xvelocity)
self.fangle = math.degrees(self.angle) + 90
self.tkimage = ImageTk.PhotoImage(self.image.rotate(-self.fangle))
self.canvas_obj = canvas.create_image(self.xpos, self.ypos, image=self.tkimage)
# 如果球的x坐标小于等于屏幕宽度和球半径的差,则调整球的运行x轴方向朝右
if self.xpos <= self.radius:
self.xvelocity = abs(self.xvelocity)
self.angle = math.atan2(self.yvelocity, self.xvelocity)
self.fangle = math.degrees(self.angle) + 90
self.tkimage = ImageTk.PhotoImage(self.image.rotate(-self.fangle))
self.canvas_obj = canvas.create_image(self.xpos, self.ypos, image=self.tkimage)
# 调整canvas对象的move()方法可以让对象动起来,以及对象x轴和y轴的向量大小
self.canvas.move(self.canvas_obj, self.xvelocity, self.yvelocity)
balls = []
num = 10
for i in range(num):
ball = Ball(canvas, tk)
ball.create_ball()
balls.append(ball)
def move_balls():
for ball in balls:
ball.move_ball()
canvas.after(20, move_balls)
if __name__ == '__main__':
tk = Tk()
tk.geometry('800x600+300+100')
tk.title('有趣的透明窗体-开篇了!!!')
tk.wm_attributes('-transparentcolor', TRANSCOLOUR)
tk.bind('' , on_resize)
canvas = Canvas(tk)
canvas.pack(fill=BOTH, expand=Y)
tk.update()
balls = []
num = 10
for i in range(num):
ball = Ball(canvas, tk)
ball.create_ball()
balls.append(ball)
move_balls()
tk.mainloop()
tk.wm_attributes("-topmost", 1)
tk.overrideredirect(1)
canvas.config(highlightthickness=0)
代码量不大,效果还行。
希望上热搜,粉丝过万,哈哈。
再深入研究可以有更多更有趣的应用。
分享是一种快乐,希望我们一起快乐,我走过的坎、尝试过的bug,希望你们可以不用再尝试。
对代码有兴趣的朋友们,欢迎关注和点赞,后续我会分享这部分的完整代码给各位,希望大家不是拿来主义,能点点赞、关注一下我啊。
欢迎持续关注,比心。