【问题标题】:Unable to update TKinter graph无法更新 TKinter 图
【发布时间】:2015-07-20 22:33:11
【问题描述】:

同事们,

我正在设计一个带有两个按钮的 GUI,一个是显示图表,每小时温度。 我面临的问题是我无法创建一个使用 self.after 更新值的函数(update_graph)。

这部分创建第 1 页,我工作正常,直到我调用 update_graph

class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self, text="Page One!!!", font=LARGE_FONT)
        label.pack(pady=10,padx=10)

        button1 = tk.Button(self, text="Back to Home",
                            command=lambda: controller.show_frame(StartPage))
        button1.pack()

        button2 = tk.Button(self, text="Page Two",
                            command=lambda: controller.show_frame(PageTwo))
        button2.pack()

        canvas = Canvas(self, width=400, height=400, bg = 'white')
        canvas.pack()

    # create x and y axes
        canvas.create_line(100,250,400,250, width=2)
        canvas.create_line(100,250,100,50,  width=2)

# creates divisions for each axle    
        for i in range(11):
            x = 100 + (i * 30)
            canvas.create_line(x,250,x,245, width=2)
            canvas.create_text(x,254, text='%d'% (10*i), anchor=N)

        for i in range(6):
            y = 250 - (i * 40)
            canvas.create_line(100,y,105,y, width=2)
            canvas.create_text(96,y, text='%5.1f'% (50.*i), anchor=E)

        self.update_graph()

    def update_graph(self):
# here is canvas create line that causes a trouble                     
        canvas.create_line(100,250,140,200, width=2)
        self.after(100,self.update_graph)


Whith this code I get an error "canvas is not defined".

If I add self to canvas in update_graph, I get

 self.canvas.create_line(100,250,140,200, width=2)
AttributeError: 'PageOne' object has no attribute 'canvas'

我在这里错过了什么?

【问题讨论】:

  • 谢谢,我自己能够使用你的“部门”循环来获得灵感

标签: user-interface python-3.x tkinter tkinter-canvas


【解决方案1】:

canvas 仅在构造函数 (__init__) 方法的范围内定义。如果您希望能够在类的其他地方访问它,则需要将其设为实例变量。而不是,

 canvas = Canvas(self, width=400, height=400, bg = 'white')

成功了,

 self.canvas = Canvas(self, width=400, height=400, bg = 'white')

现在,在代码中引用canvas 的其他任何地方,将其更改为self.canvas。这应该可以解决问题。

在一个不相关的注释中,我在update_graph 中看到的一个问题是它以递归方式或一遍又一遍地调用自身。也许你可以把它改成这样:

    def update_graph(self):
        # This line is quite long. Maybe you could shorten it?
        self.after(100, lambda: canvas.create_line(100,250,
                                                   140,200, width=2))

希望这会有所帮助!

编辑:我对@9​​87654329@ 的重新定义只有在您想要绘制一条固定线时才有意义。如果您打算添加其他功能,例如定期更新,那么原始代码是正确的,正如 Bryan 指出的那样。

【讨论】:

  • @settwi:我认为“无关注释”的建议是错误的。您使用 lambda 的解决方案没有相同的行为,因为它只会画线一次。通过after 调用update_graph 正是定期运行函数的正确解决方案。
  • @BryanOakley, update_graph 用固定参数绘制一条线。画一次还不够吗?如果它有不止一项工作要做,我就不会包含评论。也许OP打算添加其他功能,在这种情况下我错了。相应地进行了编辑。
  • @Settwi:是的,绘制一次就足够了。问题的第一部分提到他希望它每小时更新一次,所以我假设他希望更新定期发生。我猜,解决这个问题只是许多人的第一步。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-08-13
  • 2021-11-21
  • 2016-01-20
相关资源
最近更新 更多