Вы сделали очень хорошую первую попытку, и вы были почти там. Я сделал некоторые изменения в вашем коде, и самое главное, добавил объект root
(tk.Tk()
), чтобы я мог выполнить root.update () для перерисовки до sort_canvas
в новом методе blip_canvas
. Чтобы избежать некоторого «мерцания», а не разрушать холст каждый раз, лучше удалять только элементы «bar». Кроме того, я позволил себе сменить некоторые имена переменных, чтобы сделать их немного более Pythonic (следует использовать подчеркивания, а не заглавные буквы) и добавил оператор if _name__ == '__main__'
.
Посмотрите на приведенный ниже код.
import tkinter as tk
from tkinter import ttk
import random
class SortingVisualizer:
def __init__(self):
self.root = tk.Tk()
self.root.wm_title("Sorting Visualizer")
self.root.wm_minsize(width=600, height=500)
self.root.wm_resizable(width=False, height=False)
self.top_frame = tk.Frame(self.root)
self.top_frame.grid(row=0, sticky='w')
self.sort_options = ['Select Algorithm', 'Bubble sort', 'Quicksort', 'Merge sort']
self.option_var = tk.StringVar()
self.option_drop = ttk.OptionMenu(
self.top_frame, self.option_var, *self.sort_options)
self.option_drop.config(width=15)
self.option_drop.grid(row=0, column=1, sticky='ew')
self.sort_button = ttk.Button(
self.top_frame, text="Sort", command=self.bubble_sort)
self.sort_button.grid(row=0, column=2, sticky='w')
self.gen_button = ttk.Button(
self.top_frame, text="Generate New Array", command=self.new_array)
self.gen_button.grid(row=0, column=0)
self.sort_canvas = tk.Canvas(self.root)
self.bars = []
def new_array(self):
self.generate_array()
self.blip_canvas()
def generate_array(self):
self.array = []
self.num_operations = 0
i = 0
while i < 15:
height = random.randint(15, 200)
self.array.append(height)
i = i + 1
def draw_canvas(self):
label = "Number of Operations: " + str(self.num_operations)
self.num_label = tk.Label(self.top_frame, text=label)
self.num_label.grid(row=1)
self.sort_canvas = tk.Canvas(self.root, width=600, height=450)
self.sort_canvas.grid(row=1)
self.sort_canvas.create_line(15, 15, 585, 15)
bar_width = 20
bar_gap = bar_width + 10
start_x = 30
start_y = 15
self.bars = []
for bar_height in self.array:
x1 = start_x + bar_width
y1 = start_y + bar_height
self.bars.append(self.sort_canvas.create_rectangle(
start_x, start_y, x1, y1*2, fill='green'))
start_x = start_x + bar_gap
def blip_canvas(self):
self.sort_canvas.delete(self.bars)
self.draw_canvas()
self.root.update()
self.root.after(200)
def bubble_sort(self):
n = len(self.array)
for i in range(n):
for j in range(n-i-1):
if self.array[j] > self.array[j+1]:
self.array[j], self.array[j+1] = self.array[j+1], self.array[j]
self.num_operations += 1
self.blip_canvas()
def start(self):
tk.mainloop()
if __name__ == '__main__':
app = SortingVisualizer()
app.start()
Обратите внимание, что в bubble_sort вам не нужна переменная temp для обмена значениями массива [j] и массива [j +1]
Вместо того, чтобы использовать time.sleep(0.2)
для установки задержки, которую я использовал:
self.root.update()
self.root.after(200)
, как предложено в Кнопка обновления после задержки
Вы также можете придерживаться своего исходного кода и просто внести несколько изменений.
1) Измените sortButton
self.sortButton = ttk.Button(self.topFrame, text = "Sort", command=self.bubbleSort)
2) Отступ метода bubbleSort для выравнивания с SortingVisualizer
3) Измените метод redrawCanvas на:
def redrawCanvas(self):
self.sortCanvas.destroy()
self.drawCanvas()
self.update()
self.after(300)
и
4) в bubbleSort выполните вызов redrawCanvas
:
for j in range(0, n-i-1):
if self.array[j]>self.array[j+1]:
temp = self.array[j]
self.array[j] = self.array[j+1]
self.array[j+1] = temp
self.numOperations += 1
self.redrawCanvas()
et voila,это будет работать!