Tkinter 画布不会无限循环更新 [英] Tkinter canvas not updating in an infinite loop

查看:35
本文介绍了Tkinter 画布不会无限循环更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了一些代码来显示 2 个球的移动,但是当我运行它时,它没有显示球的移动.此外,它停止运行并忽略无限循环这是我到目前为止的代码:

I created some code to show 2 balls moving, but when I run it, it doesn't show the movement of the balls.Furthermore it stops running and ignores the infinite loop This is my code up to now:

import tkinter as tk

class ObjectHolder:
    def __init__(self, pos, velocity, radius, id):
        self.id = id                # the id of the canvas shape
        self.pos = pos              # the position of the object
        self.r = radius             # the radius of incluence of the object
        self.velocity = velocity    # the velocity of the object

    def moveobject(object):
        x = object.pos[0] + object.velocity[0]  # moves the object where
        y = object.pos[1] + object.velocity[1]  # 0=x and 1=y
        object.pos = (x, y)
        canvas.move(object, x, y)

class App():
    def __init__(self, canvas):
        self.canvas = canvas
        self.objects = []
        for i in range(0, 2):
            position = ((i+1)*100, (i+1)*100)
            velocity = (-(i+1)*10, -(i+1)*10)
            radius = (i + 1) * 20

            x1 = position[0]-radius
            y1 = position[1]-radius
            x2 = position[0]+radius
            y2 = position[1]+radius

            id = canvas.create_oval(x1, y1, x2, y2)
            self.objects.append(ObjectHolder(position, velocity, radius, id))
        self.symulation(self.objects)

    def symulation(self, objects):
        for object in objects:             # this moves each object
            ObjectHolder.moveobject(object)

        # This part doesn't work. It is supposed to update the canvas
        # and repeat forever.
        self.canvas.update()
        root.update()
        self.canvas.after(50, self.symulation, objects)

root = tk.Tk()
canvas = tk.Canvas(root, width=800, height=600, bg="light blue")
canvas.pack()
App(canvas)

推荐答案

您的代码存在许多问题.一大问题是您更新现有画布对象位置的方式.move() 方法需要知道移动量(x 和 y 值的变化),而不是新的绝对位置.

There are a number of issues with your code. One big one was the way you were updating the position of the existing canvas objects. The move() method needs to know the amount of movement (change in x and y value), not the new absolute position.

当我解决这个问题时,结果证明速度太大了,所以我将它们减少到只有你所拥有的值的 10%.

When I fixed that it turned out that the velocities were too big, so I reduced them to only be 10% of the values you had.

另一个问题是ObjectHolder 类的实现方式.一方面,moveobject() 方法没有 self 参数,它应该使用它而不是 object 参数.您可能还应该简单地将方法重命名为 move().

Another problem was with the way the ObjectHolder class was implemented. For one thing, the moveobject() method had no self argument, which it should have been using instead of having an object argument. You should probably also rename the method simply move().

下面的代码运行并为运动设置动画.

The code below runs and does animate the movement.

import tkinter as tk


class ObjectHolder:
    def __init__(self, pos, velocity, radius, id):
        self.id = id                # the id of the canvas shape
        self.pos = pos              # the position of the object
        self.r = radius             # the radius of incluence of the object
        self.velocity = velocity    # the velocity of the object

    def moveobject(self):
        x, y = self.pos
        dx, dy = self.velocity
        self.pos = (x + dx, y + dy)
        canvas.move(self.id, dx, dy)  # Amount of movement, not new position.


class App():
    def __init__(self, canvas):
        self.canvas = canvas
        self.objects = []
        for i in range(0, 2):
            position = ((i+1)*100, (i+1)*100)
#            velocity = (-(i+1)*10, -(i+1)*10)
            velocity = (-(i+1), -(i+1))  # Much slower speed...
            radius = (i + 1) * 20

            x1 = position[0]-radius
            y1 = position[1]-radius
            x2 = position[0]+radius
            y2 = position[1]+radius

            id = canvas.create_oval(x1, y1, x2, y2)
            self.objects.append(ObjectHolder(position, velocity, radius, id))

        self.simulation(self.objects)

    def simulation(self, objects):
        for object in objects:             # this moves each object
            object.moveobject()

        # This part doesn't work. It is supposed to update the canvas
        # and repeat forever.
#        self.canvas.update()  # Not needed.
#        root.update()  # Not needed.
        self.canvas.after(50, self.simulation, objects)

root = tk.Tk()
canvas = tk.Canvas(root, width=800, height=600, bg="light blue")
canvas.pack()
app = App(canvas)
root.mainloop()  # Added.

这篇关于Tkinter 画布不会无限循环更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆