Python Tkinter:如何让画布每帧更新多边形坐标? [解决了]
Posted
技术标签:
【中文标题】Python Tkinter:如何让画布每帧更新多边形坐标? [解决了]【英文标题】:Python Tkinter : How do I get the canvas to update polygon coordinates every frame? [solved] 【发布时间】:2022-01-21 15:44:33 【问题描述】:我正在做一个玩具项目来学习 tkinter 的基础知识。
我在np.array
对象中有一个具有位置和速度的 Drone 类,它会在每个增量时自我更新。
位置是介于 0 和 1 之间的浮点数,然后乘以高度/宽度。
我现在想看到这架无人机在屏幕上移动,所以我使用了window.after()
和window.update()
方法。
这是我写的代码:
import tkinter as tk
import numpy as np
def update_drone(canv, drone):
# update the coords of all the polygon objects with new position (scaled to screen dimensions)
canv.coords(canv.find_withtag("drone"), *([WIDTH, HEIGHT] * drone.position))
def game_loop(window, canvas, dr):
delta = 0.01
# function which updates drone's attributes
dr.update(delta)
# built in sleep
sleep(delta)
#update drone function from above
update_drone(canvas, dr)
canvas.pack()
# if the drone isnt below the screen, call the game loop next delta
if dr.position[1] < 1:
window.after(int(delta * 1000), game_loop, window, canvas, dr)
if __name__ == "__main__":
# set up window
window = tk.Tk()
window.maxsize(WIDTH, HEIGHT)
window.minsize(WIDTH, HEIGHT)
window.configure(bg="black")
# height and width are global variables i define
canvas = tk.Canvas(window, bg="black", height=HEIGHT, width=WIDTH)
# create Drone object
dr = Drone()
# call draw drone function which is defined below
draw_drone(canvas, dr)
window.after(0, game_loop, window, canvas, dr)
# main loop
window.mainloop()
我上面调用的draw_drone
函数初始化了两个多边形:
def draw_drone(canv: tk.Canvas, drone: Drone) -> None:
pos_x, pos_y = WIDTH * drone.position[0], HEIGHT * drone.position[1]
# draw drone body
size = 20
canv.create_polygon(
[
pos_x - size,
pos_y - size,
pos_x - size,
pos_y + size,
pos_x + size,
pos_y + size,
pos_x + size,
pos_y - size,
],
outline="white",
fill="yellow",
width=3,
tags="drone",
)
canv.create_polygon(
[
pos_x,
pos_y + 0.8 * size,
pos_x - 0.8 * size,
pos_y,
pos_x,
pos_y - 0.8 * size,
pos_x + 0.8 * size,
pos_y,
],
outline="red",
fill="grey",
width=8,
tags="drone",
)
当我运行上面的代码时,游戏循环被调用(当我打印出无人机位置的值时,它们确实会相应地更新)但画布在第一帧被冻结并且永远不会更新。
如果有人能告诉我问题出在哪里,我将不胜感激!
编辑:
这是我使用的基本无人机类:
class Drone:
def __init__(self):
self.position = np.array([0.5, 0.5])
self.velocity = np.array([0, 0])
self.forces = np.array([0, 0])
def update(self, dt):
self.velocity = dt * (self.forces + np.array([0, 1])) # forces + gravity
self.position += self.velocity * dt
【问题讨论】:
Drone
没有定义,你能展示一下这个类的样子吗?还提供一个完整的minimal reproducible example,顺便说一句,您不需要在任何小部件上使用update
方法
@Matiiss 感谢您的回答,我更新了我的帖子。
我找到了解决方案,更新了我最初的帖子
如果你找到了解决方案,你应该写一个答案而不是编辑你的问题
哦,非常感谢,抱歉我对 SO 比较陌生
【参考方案1】:
最后我的错误很简单。我不明白canvas.coords
是如何工作的。我的update_drone
函数的正确代码实际上是:
for t in canvas.find_withtag("drone"):
canv.coords(t, *([WIDTH, HEIGHT] * drone.position))
而不是
canv.coords(canv.find_withtag("drone"), *([WIDTH, HEIGHT] * drone.position))
这会正确更新坐标。
【讨论】:
以上是关于Python Tkinter:如何让画布每帧更新多边形坐标? [解决了]的主要内容,如果未能解决你的问题,请参考以下文章
python tkinter怎么让顶层界面有scrollbar
Python 中 Tkinter 画布上 .jpg 图像的滚动条