繁体   English   中英

Tkinter canvas create_image和create_oval优化

[英]Tkinter canvas create_image and create_oval optimization

背景

我正在尝试 - 并且成功 - 使用tkinterCanvas对象创建一个简单的绘图。 我试图尽可能多地使用与Python3一起安装的工具。 Matplotlib和其他人都很棒,但它们是相当大的安装,我试图保持一点点。

根据硬件设备的输入,图表每0.5秒更新一次。 删除前128个点,绘制当前的128个点。 有关几个屏幕截图,请参阅我最近的博文 我已经使用canvas.create_oval()成功创建了这些图,但是当我运行它时,我听到我的PC风扇增加了一点(我有一个积极的热配置文件),并意识到我使用了15%的CPU ,这似乎很奇怪。

问题

在运行cProfile之后,我发现canvas.create_oval canvas.create_oval()占用的累积时间比我预期的要多。

在读完tkinter画布中的优化之后(除了“使用其他东西”之外没有太多内容),我遇到一个帖子,建议可以使用点的图像并使用canvas.create_images()代替canvas.create_oval() 我试过了,在create_image()中的时间稍微少一些,但仍然非常重要。

为了完整起见,我将包含代码片段。 注意,此方法是一种叫做类的一部分Plot4Q是的子类tk.Canvas

def plot_point(self, point, point_format=None, fill='green', tag='data_point'):
    x, y = point

    x /= self.x_per_pixel
    y /= self.y_per_pixel

    x_screen, y_screen = self.to_screen_coords(x, y)

    if fill == 'blue':
        self.plot.create_image((x_screen, y_screen), image=self.blue_dot, tag=tag)
    else:
        self.plot.create_image((x_screen, y_screen), image=self.green_dot, tag=tag)

简介

我是一个剖析newb,所以包含该剖析器的一部分输出是谨慎的。 我按'cumtime'排序并突出了相关方法。

档案输出

  • update_plots调用scatter
  • scatter调用plot_point (上图)

请注意, scatter消耗占总运行时间的11.6%。

问题

是否有更有效的方法在画布上创建点(并删除它们,虽然在tkinter中不需要很长时间)?

如果没有,是否有更有效的方法来创建绘图并将其嵌入到tkinter界面?

我对使用不同的库有点开放,但我想保持它小而快。 我曾经认为tk画布会很小而且速度很快,因为它在具有现代PC功率的十分之一的机器上运行良好。

更多信息

在下面运行一个有用的答案(Brian Oakley)之后,我已经更新了结果。

为了解释更新的代码,我再次使用椭圆(我喜欢颜色控制)。 我检查标签是否存在。 如果它不存在,则在指定的点创建新的椭圆。 如果标记确实存在,则计算新坐标并调用move函数。

def plot_point(self, point, fill='green', tag='data_point'):
    if not fill:
        fill = self.DEFAULT_LINE_COLOR

    point_width = 2

    # find the location of the point on the canvas
    x, y = point

    x /= self.x_per_pixel
    y /= self.y_per_pixel

    x_screen, y_screen = self.to_screen_coords(x, y)

    x0 = x_screen - point_width
    y0 = y_screen - point_width
    x1 = x_screen + point_width
    y1 = y_screen + point_width

    # if the tag exists, then move the point, else create the point
    point_ids = self.plot.find_withtag(tag)

    if point_ids != ():
        point_id = point_ids[0]

        location = self.plot.coords(point_id)
        current_x = location[0]
        current_y = location[1]

        move_x = x_screen - current_x
        move_y = y_screen - current_y

        self.plot.move(point_id, move_x, move_y)

    else:
        point = self.plot.create_oval(x0,
                                      y0,
                                      x1,
                                      y1,
                                      outline=fill,
                                      fill=fill,
                                      tag=tag)

在此输入图像描述

改善幅度仅为轻微,分别为10.4%和11.6%。

创建许多项时(更具体地说,创建新的对象ID时),画布会出现性能问题。 删除对象没有帮助,问题在于不断增加的对象ID,它们永远不会被重用。 这个问题通常不会出现,直到你有成千上万的项目。 如果你创造256 /秒,你将在一两分钟内开始遇到这个问题。

如果在屏幕外创建128个对象,然后只需移动它们而不是销毁和重新创建它们,就可以完全消除这种开销。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM