【问题标题】:Animation in tkinter only works at the beginning of looptkinter 中的动画仅在循环开始时起作用
【发布时间】:2020-03-30 22:44:28
【问题描述】:

我一直在尝试使用 tkinter 在 python 中进行冒泡排序可视化,但它不起作用。当我只放几个小节时,什么也没有发生,但如果尝试放很多小节,它们会移动,看起来应该是这样(至少一开始是这样)。我的问题是,我的逻辑中是否有我看不到的错误,或者只是 tkinter?我开始认为是后者。提前致谢。这是我的代码:

import tkinter
import time
import random

width = 800
height = 800
canvas = tkinter.Canvas(height=height, width=width, background='black')
canvas.pack()

thickness = 20

values = [random.randrange(height) for i in range(width//thickness)]

cc = {}

for value in values:
    cc[value] = 0

print(values)

x1 = 0
for value in values:
    canvas.create_rectangle(x1,800, x1+thickness,value, fill='white', tag=value)
    cc[value] = x1
    x1 += thickness

for i in range(len(values)):
    for j in range(len(values)-i-1):
        if values[j] > values[j+1]:
            values[j], values[j+1] = values[j+1], values[j]
            canvas.move(values[j], cc[values[j+1]] - cc[values[j]], 0)
            canvas.move(values[j+1], cc[values[j]]- cc[values[j+1]], 0)
            cc[values[j]] += (cc[values[j+1]]- cc[values[j]])
            cc[values[j+1]] += (cc[values[j]]- cc[values[j+1]])
            canvas.update()
            canvas.after(50)
            canvas.update()
        else:
            canvas.after(5)

canvas.mainloop()

print(values)

【问题讨论】:

  • 我建议将cc 作为矩形列表。然后你不需要移动矩形,只需在交换值后根据它们所在位置的值更新它们的高度。
  • 谢谢,我已经调查过了,但你能详细说明为什么它不起作用吗?我认为我以正确的方式使用 after 方法,他们在文档中提到它也可以用作简单的 time.sleep 方法,这就是我的意图。而且我也没有看到使用函数实现矩形移动以使其更加事件驱动的简单方法,这就是我首先提出问题的原因。如果你不明白为什么这段代码不起作用,你就无法理解为什么使用 tkinter 进行事件驱动编程。

标签: python animation tkinter visualization bubble-sort


【解决方案1】:

如果values 中的多个项目具有相同的值,则使用create_rectangle() 中的tag=value 来识别矩形项目可能会出现问题。

我会使用 list 来保存矩形项目,并在排序期间根据values 中相同位置的值更新它们的高度:

import tkinter as tk
import random

width = 800
height = 800
thickness = 20

# generate values
values = [random.randrange(10, height) for i in range(width//thickness)]
print(values) # initial sequence

root = tk.Tk()

canvas = tk.Canvas(root, height=height, width=width, background='black')
canvas.pack()

# create the bars
cc = []  # hold the bar items (canvas rectangle item)
for i, value in enumerate(values):
    x = i * thickness
    item = canvas.create_rectangle(x, height, x+thickness, height-value, fill='white')
    cc.append(item)

def swap_items(a, b):
    values[a], values[b] = values[b], values[a]
    # update the bar height at positons a and b
    canvas.coords(cc[a], (a*thickness, height, (a+1)*thickness, height-values[a]))
    canvas.coords(cc[b], (b*thickness, height, (b+1)*thickness, height-values[b]))

for i in range(len(values)):
    for j in range(len(values)-i-1):
        if values[j] > values[j+1]:
            swap_items(j, j+1)
            canvas.update()
            canvas.after(50)
        else:
            canvas.after(5)
print(values) # sorted sequence

root.mainloop()

【讨论】:

  • 非常感谢!我不知道你可以这样使用 canvas.coords。它非常有帮助,因为现在我知道 tkinter 毕竟可以按预期工作。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-22
相关资源
最近更新 更多