2

I'm trying to implement a particle filter and I chose python for it because I kinda like python. By now i have written my gui using tkinter and python 3.4.

I use the tkinter.canvas object to display a map (png image loaded with PIL) and then i create dots for each particle like:

dot = canvas.create_oval(x, y, x + 1, y + 1)

When the robot moves I calculate the new position of each particle with the control command of the robot, the particles position and the particles alignment. To move the particle tkinter.canvas has two methods:

canvas.move()
canvas.coords()

But both methods seem to update the gui immediately which is OK when there are about 100 particles but not if there are 200 - 5000 (what I actually should have in the beginning for the global localization). So my problem is the performance of the gui.

So my actual question is: Is there a way in tkinter to stop the canvas from updating the gui, then change the gui and then update the gui again? Or can you recommend me a module that is better than tkinter for my use-case?

4

1 回答 1

1

你的观察不正确。画布不会立即更新。在事件循环能够处理事件之前,不会重绘椭圆形。在重新绘制画布之前,很有可能更新数千个对象。但是,画布不是一种高性能工具,因此以高帧速率移动数千个对象将很困难。

如果您看到对象立即更新,可能是因为您在代码中的某处调用update, update_idletasks,或者您允许事件循环运行。

那么,您的问题的具体答案是确保您不调用updateor update_idletasks,或者让事件循环处理事件,直到您更改了所有粒子的坐标。

下面是一个简短的例子。当它运行时,请注意所有粒子都以一秒的间隔同时移动。这是因为所有计算都是在允许事件循环重绘画布上的项目之前完成的。

import Tkinter as tk
import random

class Example(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)

        self.canvas = tk.Canvas(self, width=500, height=500, background="black")
        self.canvas.pack(fill="both", expand=True)

        self.particles = []
        for i in range(1000):
            x = random.randint(1, 499)
            y = random.randint(1, 499)
            particle = self.canvas.create_oval(x,y,x+4,y+4,
                                               outline="white", fill="white")
            self.particles.append(particle)

        self.animate()


    def animate(self):
        for i, particle in enumerate(self.particles):
            deltay = (2,4,8)[i%3]
            deltax = random.randint(-2,2)
            self.canvas.move(particle, deltax, deltay)

        self.after(30, self.animate)

if __name__ == "__main__":
    root = tk.Tk()
    Example(root).pack(fill="both", expand=True)
    root.mainloop()
于 2015-12-22T14:10:14.487 回答