为什么即使使用跟踪和回调函数,GUI 也不会更新?

Why doesn't the GUI update even with trace and a callback function?

我很难弄清楚为什么即使我使用了 tkinter 变量、.trace 方法和 .update 方法,以下代码也不会更新。

    from tkinter import *
    from math import sin, cos, pi
    master = Tk()


    people_size_var = IntVar()

    PeopleSize = Scale(master, from_=1, to=50, bd=3, length=153, variable=people_size_var)
    PeopleSize.grid(row=2, column=4, padx=10, pady=5)
    people_size_var.set(20)
    PeopleSize.config(highlightbackground="white")

    def update_canvas(*args):
        DisplayFrame.update()

    people_size_var.trace("w", update_canvas)

    a = 350
    b = 140
    ellipsePoints = [(a * cos(theta), b * sin(theta))
                     for theta in (pi*2 * i/number_of_people for i in range(number_of_people))]
    DisplayFrame = Canvas(master, bg="white", width=725, height=320)
    DisplayFrame.grid(row=0, columnspan=7, column=0, sticky='W', padx=5, pady=5)


    for i in range(number_of_people-1):
        Bonds = DisplayFrame.create_line(ellipsePoints[i][0]+355+(node_size/2), ellipsePoints[i][1]+155+(node_size/2),
                                 ellipsePoints[i+1][0]+355+(node_size/2), ellipsePoints[i+1][1] +155+(node_size/2),
                                 width=2, fill="black")

    for i in range(number_of_people):
        People = DisplayFrame.create_oval(ellipsePoints[i][0]+355, ellipsePoints[i][1]+155,
                                 ellipsePoints[i][0]+355 + node_size, ellipsePoints[i][1] + 155 + node_size,
                                 fill="yellow", outline="black", width=2)





    master.mainloop()

因此,如您所见,我的代码在 Canvas (DisplayFrame) 中绘制了一些圆圈和圆圈之间的线。每次 people_size_var 更改时,我都会尝试更新 canvas,但它不起作用。跟踪确实有效,只是更新功能无效。我对所有这些 tkinter 东西还是陌生的,所以我真的不知道如何找出代码有什么问题。终端中没有任何错误。

我认为你不需要在这里使用 update() 方法。您已经有一个无限循环 运行,主(事件)循环。你可以直接使用它。

因为你想在每次比例变化时绘制整个东西,你需要把绘图的东西放在你的回调中,但一定不要在每个回调中创建另一个 canvas,所以你需要把 在函数之外创建 canvas 内容,并每次清除 canvas 以在其上绘制新内容。

我假设 node_size 是一个常数,number_of_people 随比例变化。

from tkinter import *
from math import sin, cos, pi
master = Tk()

def update_canvas(*args):
    number_of_people = people_size_var.get() #gets scale's value
    DisplayFrame.delete("all") #deletes every content from canvas

    a = 350
    b = 140
    ellipsePoints = [(a * cos(theta), b * sin(theta))
                     for theta in (pi*2 * i/number_of_people for i in range(number_of_people))]

    for i in range(number_of_people-1):
        Bonds = DisplayFrame.create_line(ellipsePoints[i][0]+355+(node_size/2), ellipsePoints[i][1]+155+(node_size/2),
                                 ellipsePoints[i+1][0]+355+(node_size/2), ellipsePoints[i+1][1] +155+(node_size/2),
                                 width=2, fill="black")

    for i in range(number_of_people):
        People = DisplayFrame.create_oval(ellipsePoints[i][0]+355, ellipsePoints[i][1]+155,
                                 ellipsePoints[i][0]+355 + node_size, ellipsePoints[i][1] + 155 + node_size,
                                 fill="yellow", outline="black", width=2)

people_size_var = IntVar()
PeopleSize = Scale(master, from_=1, to=50, bd=3, length=320, variable=people_size_var)
PeopleSize.grid(row=0, column=0, padx=10, pady=5)
people_size_var.set(20)
PeopleSize.config(highlightbackground="white")

node_size = 5

DisplayFrame = Canvas(master, bg="white", width=725, height=320)
DisplayFrame.grid(row=0, columnspan=7, column=1, sticky='W', padx=5, pady=5)

people_size_var.trace("w", update_canvas)

master.mainloop()