在tkinter中生成动画 [英] generating animation in tkinter
问题描述
我使用 tkinter
编写了一个小程序,基于我给程序提供的参数(通过 gui
界面)生成图形.我正在使用 Canvas
用 tkinter
直接绘制图形.现在,我想生成一系列图形并将它们置于动画循环中.我可以生成一个 gif
动画,然后将其加载到图中,但问题是我是否可以直接在 tkinter
中执行此操作.我可以将所有内容放入循环中,但随后我将丢失事件处理程序.还有其他选择吗?
I wrote a small program using tkinter
to generate a figure based on parameters I'm giving the program (through gui
interface). I am drawing the figure directly with tkinter
using Canvas
. Now I want to generate a series of figures and put them in animated loop. I can generate a gif
animation and load it into the figure but the question is if I can do this directly in tkinter
. I can put everything in loop, but then I'll lose the event handler. Any other option?
编辑
这是一个简单的脚本:
#!/usr/bin/python
from Tkinter import *
import ttk
import numpy as np
colors = {1:'#F00',
2:'#0F0',
3:'#00F',
4:'#FF0',
5:'#0FF'}
root = Tk()
canvas = Canvas(root,width=400,height=400)
label = Label(root,text='seed')
values = StringVar()
combo = ttk.Combobox(root)
def painter(event):
seed = int(combo.get())
np.random.seed(seed)
nrows = 10
ncols = 10
Y = 0
dx = 400/nrows
dy = 400/ncols
for i in range(nrows):
X = 0
for j in range(ncols):
n = np.random.randint(1,5)
col = colors[n]
canvas.create_rectangle(X,Y,X+dx,Y+dy,width=1,fill=col)
X += dx
Y += dy
canvas.grid(column=0,row=0,rowspan=2)
combo.grid(row=1,column=1)
label.grid(row=0,column=1)
combo['values'] = [1,2,3,4]
combo.bind('<<ComboboxSelected>>',painter)
combo.current(0)
painter(None)
root.mainloop()
我可以更改 painter
函数以包含一个无限循环,但是这样我就永远不会到达 mainloop()
,因此我只需要在主循环之后调用它被创建,但是如何?
I could change the painter
function to include an infinite loop but this way I never reach the mainloop()
, so I need to call this only after the main loop is created, but how?
推荐答案
使用tkinter画布的一些动画的简单示例:
a simple example of some animation using tkinter canvas:
import tkinter as tk
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("Canvas animation example")
self.c = tk.Canvas(self, width=400, height=400)
self.c.pack()
self.f_index = 0 # index so we know which frame to draw next
# array to hold our frame data,
# you'll probably need this to hold more than
# just a set of coordinates to draw a line...
self.f_data = []
for num in range(0, 400, 5): # make up a set of fake data
self.f_data.append([num, num, num+10, num+10])
def next_frame(self):
data = self.f_data[self.f_index] # fetch frame data
self.c.delete('all') # clear canvas
self.c.create_line(*data) # draw new frame data
self.f_index += 1 # increment frame index
if (self.f_index >= len(self.f_data)): # check and wrap if at end of sequence
self.f_index = 0
self.c.after(50, self.next_frame) # call again after 50ms
if __name__ == "__main__":
app = App()
app.next_frame() # called manually once to start animation
# could be started with 'after' instead if desired
app.mainloop()
请注意,要删除和重绘的项目越多,此代码执行的速度就越慢.您需要有现实的期望,在一个像样的PC上画几张纸就可以了,几百张纸就可以,但是1000张纸的表现会很差.
note that the more items you want to delete and redraw the slower this code will perform. you need to have realistic expectations, drawing a few 10's of items will be fine, a few 100's might be ok on a decent pc, but 1000's of items would be very poorly performing.
这篇关于在tkinter中生成动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!