如何使 tkinter canvas 更新?
how to make tkinter canvas update?
我在 tkinter canvas 中编写了一个条形图,它正在从列表中获取数据。但是,当我更新列表时,条形图不会更新。我该如何解决这个问题?
我的代码看起来像这样:
import tkinter as tk
import random
data = [20, 15, 10, 7, 5, 4, 3, 2, 1, 1, 0]
root = tk.Tk()
root.title("Bar Graph")
c_width = 600 # Define it's width
c_height = 400 # Define it's height
c = tk.Canvas(root, width=c_width, height=c_height, bg='white')
c.pack()
# The variables below size the bar graph
y_stretch = 15 # The highest y = max_data_value * y_stretch
y_gap = 20 # The gap between lower canvas edge and x axis
x_stretch = 10 # Stretch x wide enough to fit the variables
x_width = 20 # The width of the x-axis
x_gap = 20 # The gap between left canvas edge and y axis
# A quick for loop to calculate the rectangle
for x, y in enumerate(data):
# coordinates of each bar
# Bottom left coordinate
x0 = x * x_stretch + x * x_width + x_gap
# Top left coordinates
y0 = c_height - (y * y_stretch + y_gap)
# Bottom right coordinates
x1 = x * x_stretch + x * x_width + x_width + x_gap
# Top right coordinates
y1 = c_height - y_gap
# Draw the bar
c.create_rectangle(x0, y0, x1, y1, fill="red")
# Put the y value above the bar
c.create_text(x0 + 2, y0, anchor=tk.SW, text=str(y))
root.mainloop()
def update():
count = 0
while count < 5:
barChartData.append(random.randint(1, 11))
count = count + 1
update()
update()
我该如何解决这个问题?
每次更改数字时,您都需要删除旧图表并创建新图表。
您应该通过将绘制条形图的代码移动到一个函数中来做到这一点。
def draw_barchart(data):
c.delete("all")
for x, y in enumerate(data):
x0 = x * x_stretch + x * x_width + x_gap
y0 = c_height - (y * y_stretch + y_gap)
x1 = x * x_stretch + x * x_width + x_width + x_gap
y1 = c_height - y_gap
c.create_rectangle(x0, y0, x1, y1, fill="red")
c.create_text(x0 + 2, y0, anchor=tk.SW, text=str(y))
您可以在数据发生变化时调用它,传入新数据。
但是,您的代码还有其他问题。您需要在程序的最后调用 mainloop()
,因为在 window 被销毁之前它不会 return。
您还需要使用 after
定期更新数据,或调用 tkinter 的 update
函数以允许 window 重绘自身。
下面是如何编写代码的底部以添加数据并每五秒重绘一次图形:
def update():
count = 0
for i in range(5):
data.append(random.randint(1, 11))
c.delete("all")
draw_barchart(data)
root.after(5000, update)
update()
root.mainloop()
我在 tkinter canvas 中编写了一个条形图,它正在从列表中获取数据。但是,当我更新列表时,条形图不会更新。我该如何解决这个问题?
我的代码看起来像这样:
import tkinter as tk
import random
data = [20, 15, 10, 7, 5, 4, 3, 2, 1, 1, 0]
root = tk.Tk()
root.title("Bar Graph")
c_width = 600 # Define it's width
c_height = 400 # Define it's height
c = tk.Canvas(root, width=c_width, height=c_height, bg='white')
c.pack()
# The variables below size the bar graph
y_stretch = 15 # The highest y = max_data_value * y_stretch
y_gap = 20 # The gap between lower canvas edge and x axis
x_stretch = 10 # Stretch x wide enough to fit the variables
x_width = 20 # The width of the x-axis
x_gap = 20 # The gap between left canvas edge and y axis
# A quick for loop to calculate the rectangle
for x, y in enumerate(data):
# coordinates of each bar
# Bottom left coordinate
x0 = x * x_stretch + x * x_width + x_gap
# Top left coordinates
y0 = c_height - (y * y_stretch + y_gap)
# Bottom right coordinates
x1 = x * x_stretch + x * x_width + x_width + x_gap
# Top right coordinates
y1 = c_height - y_gap
# Draw the bar
c.create_rectangle(x0, y0, x1, y1, fill="red")
# Put the y value above the bar
c.create_text(x0 + 2, y0, anchor=tk.SW, text=str(y))
root.mainloop()
def update():
count = 0
while count < 5:
barChartData.append(random.randint(1, 11))
count = count + 1
update()
update()
我该如何解决这个问题?
每次更改数字时,您都需要删除旧图表并创建新图表。
您应该通过将绘制条形图的代码移动到一个函数中来做到这一点。
def draw_barchart(data):
c.delete("all")
for x, y in enumerate(data):
x0 = x * x_stretch + x * x_width + x_gap
y0 = c_height - (y * y_stretch + y_gap)
x1 = x * x_stretch + x * x_width + x_width + x_gap
y1 = c_height - y_gap
c.create_rectangle(x0, y0, x1, y1, fill="red")
c.create_text(x0 + 2, y0, anchor=tk.SW, text=str(y))
您可以在数据发生变化时调用它,传入新数据。
但是,您的代码还有其他问题。您需要在程序的最后调用 mainloop()
,因为在 window 被销毁之前它不会 return。
您还需要使用 after
定期更新数据,或调用 tkinter 的 update
函数以允许 window 重绘自身。
下面是如何编写代码的底部以添加数据并每五秒重绘一次图形:
def update():
count = 0
for i in range(5):
data.append(random.randint(1, 11))
c.delete("all")
draw_barchart(data)
root.after(5000, update)
update()
root.mainloop()