在 mainloop() 中更新 Tkinter canvas
Update Tkinter canvas in mainloop()
我正在尝试在 Tkinter 中创建一个简单的冒泡排序可视化,但我不知道如何更新 canvas/refresh。
from tkinter import *
import random
height, width = 350,600
randomLines = []
master = Tk()
w = Canvas(master,width=width,height=height)
w.pack()
def drawRandomLines():
w.delete("all")
for i in range(width):
w.create_line(i,0,i,randomLines[i])
def bubbleSort():
for passnum in range(len(randomLines)-1,0,-1):
for i in range(passnum):
if randomLines[i]>randomLines[i+1]:
temp = randomLines[i]
randomLines[i] = randomLines[i+1]
randomLines[i+1] = temp
for i in range(width):
rnd = random.randint(0,width)
randomLines.append(rnd)
drawRandomLines()
bubbleSort()
mainloop()
如果我在 bubbleSort() 循环中使用 drawRandomLines() 它将保存 window 并且不会显示 canvas 直到它被排序
您将要使用 after()
来管理不会影响主循环的更新循环。通过使用 after()
我们可以随着时间的推移创建视觉更新。我们需要一个跟踪变量来管理循环中的索引和跟踪器的全局语句。
示例:
from tkinter import *
import random
height, width = 350, 600
randomLines = []
master = Tk()
tracker = 0
w = Canvas(master, width=width, height=height)
w.pack()
def drawRandomLines():
global tracker
if tracker <= width:
w.create_line(tracker, 0, tracker, randomLines[tracker])
tracker += 1
master.after(10, drawRandomLines)
def bubbleSort():
for passnum in range(len(randomLines)-1, 0, -1):
for i in range(passnum):
if randomLines[i] > randomLines[i+1]:
temp = randomLines[i]
randomLines[i] = randomLines[i+1]
randomLines[i+1] = temp
for i in range(width):
rnd = random.randint(0, width)
randomLines.append(rnd)
drawRandomLines()
bubbleSort()
mainloop()
Tkinter 不会更新 window 直到重要事情队列完成。因此,如果您希望每次迭代都更新,则必须强制执行它。试试这个:
def drawRandomLines():
w.delete("all")
for i in range(width):
w.create_line(i,0,i,randomLines[i])
w.update() # Force canvas update
您可以使用after()
替换bubbleSort()
中的外部for
循环并在bubbleSort()
中调用drawRandomLines()
:
from tkinter import *
import random
height, width = 350, 600
thickness = 5
# create the random lines
randomLines = [random.randint(1, height-1) for i in range(0, width, thickness)]
master = Tk()
w = Canvas(master, width=width, height=height)
w.pack()
def drawRandomLines():
w.delete("all")
for i in range(len(randomLines)):
x = i * thickness
# use bars for more clearly presentation
w.create_rectangle(x, height, x+thickness, height-randomLines[i], fill='red')
def bubbleSort(passnum):
for i in range(passnum):
if randomLines[i] > randomLines[i+1]:
randomLines[i], randomLines[i+1] = randomLines[i+1], randomLines[i]
drawRandomLines()
if passnum > 0:
master.after(20, bubbleSort, passnum-1)
else:
w.create_text(50, 50, text='Done!', font=('Arial', 24))
drawRandomLines() # show initial order of lines
bubbleSort(len(randomLines)-1)
master.mainloop()
我正在尝试在 Tkinter 中创建一个简单的冒泡排序可视化,但我不知道如何更新 canvas/refresh。
from tkinter import *
import random
height, width = 350,600
randomLines = []
master = Tk()
w = Canvas(master,width=width,height=height)
w.pack()
def drawRandomLines():
w.delete("all")
for i in range(width):
w.create_line(i,0,i,randomLines[i])
def bubbleSort():
for passnum in range(len(randomLines)-1,0,-1):
for i in range(passnum):
if randomLines[i]>randomLines[i+1]:
temp = randomLines[i]
randomLines[i] = randomLines[i+1]
randomLines[i+1] = temp
for i in range(width):
rnd = random.randint(0,width)
randomLines.append(rnd)
drawRandomLines()
bubbleSort()
mainloop()
如果我在 bubbleSort() 循环中使用 drawRandomLines() 它将保存 window 并且不会显示 canvas 直到它被排序
您将要使用 after()
来管理不会影响主循环的更新循环。通过使用 after()
我们可以随着时间的推移创建视觉更新。我们需要一个跟踪变量来管理循环中的索引和跟踪器的全局语句。
示例:
from tkinter import *
import random
height, width = 350, 600
randomLines = []
master = Tk()
tracker = 0
w = Canvas(master, width=width, height=height)
w.pack()
def drawRandomLines():
global tracker
if tracker <= width:
w.create_line(tracker, 0, tracker, randomLines[tracker])
tracker += 1
master.after(10, drawRandomLines)
def bubbleSort():
for passnum in range(len(randomLines)-1, 0, -1):
for i in range(passnum):
if randomLines[i] > randomLines[i+1]:
temp = randomLines[i]
randomLines[i] = randomLines[i+1]
randomLines[i+1] = temp
for i in range(width):
rnd = random.randint(0, width)
randomLines.append(rnd)
drawRandomLines()
bubbleSort()
mainloop()
Tkinter 不会更新 window 直到重要事情队列完成。因此,如果您希望每次迭代都更新,则必须强制执行它。试试这个:
def drawRandomLines():
w.delete("all")
for i in range(width):
w.create_line(i,0,i,randomLines[i])
w.update() # Force canvas update
您可以使用after()
替换bubbleSort()
中的外部for
循环并在bubbleSort()
中调用drawRandomLines()
:
from tkinter import *
import random
height, width = 350, 600
thickness = 5
# create the random lines
randomLines = [random.randint(1, height-1) for i in range(0, width, thickness)]
master = Tk()
w = Canvas(master, width=width, height=height)
w.pack()
def drawRandomLines():
w.delete("all")
for i in range(len(randomLines)):
x = i * thickness
# use bars for more clearly presentation
w.create_rectangle(x, height, x+thickness, height-randomLines[i], fill='red')
def bubbleSort(passnum):
for i in range(passnum):
if randomLines[i] > randomLines[i+1]:
randomLines[i], randomLines[i+1] = randomLines[i+1], randomLines[i]
drawRandomLines()
if passnum > 0:
master.after(20, bubbleSort, passnum-1)
else:
w.create_text(50, 50, text='Done!', font=('Arial', 24))
drawRandomLines() # show initial order of lines
bubbleSort(len(randomLines)-1)
master.mainloop()