Python Tkinter动画

Python Tkinter动画,python,animation,python-2.7,tkinter,Python,Animation,Python 2.7,Tkinter,为什么动画不起作用?当我运行程序时,形状不会移动 from Tkinter import * import time class alien(object): def __init__(self): self.root = Tk() self.canvas = Canvas(self.root, width=400, height = 400) self.canvas.pack() alien1 = self.can

为什么动画不起作用?当我运行程序时,形状不会移动

from Tkinter import *
import time



class alien(object):
     def __init__(self):
        self.root = Tk()
        self.canvas = Canvas(self.root, width=400, height = 400)
        self.canvas.pack()
        alien1 = self.canvas.create_oval(20, 260, 120, 360, outline='white',         fill='blue')
        alien2 = self.canvas.create_oval(2, 2, 40, 40, outline='white', fill='red')
        self.canvas.pack()
        self.root.mainloop()

     def animation(self):
        track = 0
        while True:
        x = 5
        y = 0
        if track == 0:
           for i in range(0,51):
                self.time.sleep(0.025)
                self.canvas.move(alien1, x, y)
                self.canvas.move(alien2, x, y)
                self.canvas.update()
           track = 1
           print "check"

        else:
           for i in range(0,51):
                self.time.sleep(0.025)
                self.canvas.move(alien1, -x, y)
                self.canvas.move(alien2, -x, y)
                self.canvas.update()
           track = 0
        print track

alien()
您从未调用过动画方法。还有一些其他命名问题

# Assuming Python 2.x
# For Python 3.x support change print -> print(..) and Tkinter to tkinter
from Tkinter import *
import time

class alien(object):
     def __init__(self):
        self.root = Tk()
        self.canvas = Canvas(self.root, width=400, height = 400)
        self.canvas.pack()
        self.alien1 = self.canvas.create_oval(20, 260, 120, 360, outline='white',         fill='blue')
        self.alien2 = self.canvas.create_oval(2, 2, 40, 40, outline='white', fill='red')
        self.canvas.pack()
        self.root.after(0, self.animation)
        self.root.mainloop()

     def animation(self):
        track = 0
        while True:
            x = 5
            y = 0
            if track == 0:
               for i in range(0,51):
                    time.sleep(0.025)
                    self.canvas.move(self.alien1, x, y)
                    self.canvas.move(self.alien2, x, y)
                    self.canvas.update()
               track = 1
               print "check"

            else:
               for i in range(0,51):
                    time.sleep(0.025)
                    self.canvas.move(self.alien1, -x, y)
                    self.canvas.move(self.alien2, -x, y)
                    self.canvas.update()
               track = 0
            print track

alien()
您的动画方法中有一个while True循环,它从不中断。这在GUI程序中是不允许的,因为它从不返回,从而阻止GUI的事件循环处理事件。因此,例如,如果您有一个菜单,那么用户将无法选择任何菜单项。GUI将显示为冻结状态,除了在动画方法中实现的任何操作

这里是对@Tim代码的一个轻微修改,它通过删除while循环并在返回之前将外星人移动一步来修复这个问题。在动画方法结束时调用self.master.after,以使事件循环在短暂暂停后再次调用动画


这里有一种使用循环的方法:

from tkinter import * # version 3.x

tk = Tk()

frame = Frame(tk)
canvas = Canvas(frame) # use canvas

frame.pack(fill = BOTH, expand = 1)
canvas.pack(fill = BOTH, expand = 1)

ball = canvas.create_oval(10, 10, 30, 30, tags = 'ball') # create object to animate

def animation(x_move, y_move):
    canvas.move(ball, x_move, y_move) # movement
    canvas.update()
    canvas.after(20) # milliseconds in wait time, this is 50 fps

    tk.after_idle(animation, x_move, y_move) # loop variables and animation, these are updatable variables

animation(2, 2) # run animation

可更新变量是一个在更新时保持不变并可再次更新的变量。

更多问号请尝试使椭圆在x轴上从左向右移动是否有需要导入的内容?因为我在网上查了论坛,只导入Tkinter和timer是有意义的,不确定我遗漏了什么哇,我不会犯这些错误,你能给我一些如何成为优秀程序员的建议吗?任何网站或书籍,可以帮助我提高这个爱好,因为我觉得它非常有趣。。。。非常感谢你,先生!!!尽可能多地练习,注意小细节。在本例中,所有命名问题都是通过在程序运行时读取错误消息来识别的。在代码中加入睡眠是个坏主意。尽管它们很短,但每次睡眠时,整个GUI都会无响应。o ic,但Tkinter import*和作为tk导入Tkinter之间的区别是什么?Tkinter import*导入Tkinter模块,并将Tkinter模块中的所有公共全局变量添加到当前模块的命名空间中。import Tkinter as tk导入Tkinter模块,并将模块对象本身(由tk引用)添加到当前模块的命名空间中。我从不使用from modulename import*,因为它使跟踪变量的来源变得更加困难。有关在模块中使用导入的最佳实践的建议,请参阅。@unutbu Nice,如果我们想在动画中使用更复杂的gui,我们将动画放在动画方法中,然后gui本身(带有类似事件管理的内容)应位于self.master.after之后的uuuuuuuuuuu_uuuuuuuu函数中,或由uuuuuuuuuuuuuuu函数调用。我是对的?或者应该是在之前?@Yann:我会像平常一样构建GUI,这通常是在应用程序中完成的。uuu init_uuu,在应用程序的末尾。uuu init_u,调用self.master.after0,self.animation。可以这样想:您将所有小部件放在适当的位置,然后将调用self.animation的动作添加到事件循环中。@unutbu ok ty!我在上面。感受python的强大:3通过删除canvas.update和canvas,我得到了一个更加流畅的程序。。。而不是使用canvas.after20,动画,x_移动,y_移动。在最后一行之后添加TK.MILROLL。我被告知,但我现在使用高级的OpenGL,在C++中有着色器和3D照明,谢谢输入!不过Opengl比tkinter好。。。
from tkinter import * # version 3.x

tk = Tk()

frame = Frame(tk)
canvas = Canvas(frame) # use canvas

frame.pack(fill = BOTH, expand = 1)
canvas.pack(fill = BOTH, expand = 1)

ball = canvas.create_oval(10, 10, 30, 30, tags = 'ball') # create object to animate

def animation(x_move, y_move):
    canvas.move(ball, x_move, y_move) # movement
    canvas.update()
    canvas.after(20) # milliseconds in wait time, this is 50 fps

    tk.after_idle(animation, x_move, y_move) # loop variables and animation, these are updatable variables

animation(2, 2) # run animation