gpt4 book ai didi

python - Tkinter Canvas 更新圆圈闪烁

转载 作者:太空宇宙 更新时间:2023-11-03 19:55:50 29 4
gpt4 key购买 nike

我正在尝试使用 tkinter 用 python 显示一个简单的摆。我正在使用 scipy 模块求解微分方程,然后显示每 10 毫秒更新一次角度的摆锤,但代表质量的圆圈正在闪烁,我不知道是否有任何方法可以解决这个问题,如果没有,应该我使用的模块与 tkinter 不同?

import math
from scipy.integrate import odeint
import tkinter as tk




class Pendulum:
def __init__(self, root, l1, m1, theta1, theta1_v = 0, tmax = 10, g = 9.81):
#initialization of the screen
self.root = root
self.root.minsize(480,480)
self.root.maxsize(480,480)
self.canvas = tk.Canvas(self.root, width = 480, height = 480, bg ='white')
self.canvas.pack()

#initialization of the pendulum
self.l1 =l1
self.l1p = self.l1* 100
self.m1 = m1
self.theta1 = theta1
self.theta1_v = theta1_v
self.tmax = tmax
self.g = g
self.x0 = 240
self.y0 = 50
self.x1 = self.x0 + self.l1p * math.sin(self.theta1)
self.y1 = self.y0 + self.l1p * math.cos(self.theta1)

#initialization of the different time
#to solve the differencial equation
self.t = [k/100 for k in range(100*self.tmax)]

#solving the differencial equation and saving the result
self.theta_list = self.calc_theta()

#Display the initial condition
self.canvas.create_oval(self.x0-2,self.y0-2,self.x0+2,self.y0+2, fill = 'black')
self.canvas.create_oval((self.x1-self.m1),(self.y1-self.m1),(self.x1+self.m1), (self.y1+self.m1), fill = 'black', tags = 'mass')
self.canvas.create_line(self.x0,self.y0,self.x1,self.y1,fill = 'black', tags='line')

#counter to keep track of the correct angle to display
self.i = 0


def f(self,y,t): #function of the differential equation
return [y[1], -(self.g / self.l1) * math.sin(y[0])]

def calc_theta(self): #resolving the differential equation
return odeint(self.f,[self.theta1, self.theta1_v],self.t)

def update(self): #updating the screen
if self.i == 100* self.tmax -1:
self.root.destroy
return

self.theta1 = self.theta_list[self.i][0] #take the next angle

#updating the pendulum
self.x1 = self.x0 + self.l1p * math.sin(self.theta1)
self.y1 = self.y0 + self.l1p * math.cos(self.theta1)
self. i +=1

#updating the screen
self.canvas.delete('all')
self.canvas.create_oval(self.x0-2,self.y0-2,self.x0+2,self.y0+2, fill = 'black')
self.canvas.create_oval((self.x1-self.m1),(self.y1-self.m1),(self.x1+self.m1), self.y1+self.m1), fill = 'black', tags = 'mass')
self.canvas.create_line(self.x0,self.y0,self.x1,self.y1,fill = 'black', tags='line')

#call update every 10ms
self.root.after(10,self.update)

window = tk.Tk()
p = Pendulum(window,1,10,math.pi/2, 0, 5)
p.update()
window.mainloop()

最佳答案

我同意@martineau的评论。为了证明他的假设,这里有一个示例代码,显示 3 个弹跳圆圈的动画,定义为 Canvas 上的 oval 对象。正如您所看到的,通过更新椭圆坐标,而不是删除/重新创建它们,观察不到闪烁:

from tkinter import *

def tick():
for item in items:
xa, ya, xb, yb = canvas.coords(item[0]) # get item coordinates
vx, vy = item[1:3] # get item velocity
xa, ya = xa + vx, ya + vy # edit item coordinates by adding velocity
xb, yb = xb + vx, yb + vy
if xa < 0 or xb > width: vx = -vx # horizontal bounce (reverse vx)
if ya < 0 or yb > height: vy = -vy # vertical bounce (reverse vy)
canvas.coords(item[0], xa, ya, xb, yb) # update position
item[1:3] = vx, vy # update velocity
win.after(10, tick) # recursive call of 'tick' after 10ms

win = Tk()
width, height = 640, 480
items, colors = [], ('#F00','#0F0','#00F','#000')

canvas = Canvas(win, width=width, height=height, relief=SOLID, border=5)
canvas.pack()

for n in range(3):
# define dimension, position and velocity for each item
dim, dx, dy = min(width,height)/8, width/4, height/4
x, y, vx, vy = dx + n*dx, dy + n*dy, 3-n, n+1
items.append([canvas.create_oval(x-dim, y-dim, x+dim, y+dim,
width=5, outline=colors[3], fill=colors[n]), vx, vy])

win.after(1000, tick) # start animation after 1000ms
win.mainloop()

也就是说,我必须同意 tkinter 并不是为了制作超快动画......

关于python - Tkinter Canvas 更新圆圈闪烁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59545119/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com