Как удалить и воссоздать холст? (ТКИНТЕР / ХОЛСТ) - PullRequest
1 голос
/ 04 августа 2020

Я ищу часы на net, как удалить и затем воссоздать «холст» на Tkinter.

Итак, сначала мой код:

import tkinter as tk
import time
import numpy as np
m = 100
matrice = np.zeros((m,m))
matrice[10][10] = 1

root = tk.Tk()
root.title("Test")
root.geometry('1200x800')
canvas = tk.Canvas(width = 700 , height = 700)

def trace(m) :
    global canvas
    m2 = int(700/m)
    canvas.destroy()
    canvas = tk.Canvas(width = 700 , height = 700)
    for i in range(0,m) :
        for j in range(0,m) : 
            x = m2*i
            y = m2*j
            canvas.create_rectangle(x , y , m2+x , m2+y,outline = 'grey' , width = 1)

def affiche_points(m,matrice) :
    global canvas
    m2 = int(700/m)
    for i in range(m):
        for j in range(m):
            if matrice[i][j] == 1 :
                x = m2*i
                y = m2*j
                canvas.create_rectangle(x , y , m2+x , m2+y , fill = 'black')


def actualisation(m,matrice) :
    global canvas
    trace(m)
    affiche_points(m,matrice)
    canvas.pack()


actualisation(m,matrice)

for i in range(0,20) :

    matrice = np.zeros((m,m)) 
    matrice[i][10] = 1
    actualisation(m,matrice)
    time.sleep(0.5) 



root.mainloop()

Я просто хочу создайте сетку, и когда элемент в матрице изменится, сетка тоже изменится (0 = белый и 1 = черный). В моем случае я использую

canvas.destroy()

, чтобы очистить окно

и i подождите 0,5 секунды с time.sleep (), пока я не покажу новое изображение из матрицы.

Моя проблема в том, что я не вижу актуализации: (

Я вижу только последний кадр! Я не знаю, является ли это canvas.pack () или что-то в этом роде, которое нельзя обновить.

NB: это упрощение для более крупного плана!

NB 2: Извините за мой странный английский sh я француз, знаете ли ...

СПАСИБО

1 Ответ

1 голос
/ 04 августа 2020

Объяснение

Очевидно, что этот вопрос состоит из двух частей:

  1. Как получить сохраняемую структуру деталей для каждого элемента, находящегося в данный момент на холсте (ведение журнала вручную какие элементы мы добавляем и удаляем, это настоящая проблема, поэтому мы проигнорируем это как решение)
  2. Как восстановить элементы из этого сохраненного состояния

Для первой части проблема, я считаю, что есть еще три части, которые необходимо рассмотреть *, а именно:

  1. Как получить тип объекта холста (линия, прямоугольник и т. д. c.) . Это оказывается довольно просто, так как есть метод Canvas.type, который мы можем использовать.
  2. Как получить координаты элемента. Это не так очевидно и требует некоторых знаний Tcl, чтобы получить решение. Решение состоит в том, чтобы использовать Canvas.coords, а документация tkinter не объясняет, что если этот метод вызывается без каких-либо координат (предоставляется только item), он вернет текущие координаты данный элемент (а не изменять их).
  3. Как получить параметры и их значения для элемента. Как и выше, решение для этого требует небольшого понимания Tcl. Решение состоит в том, чтобы использовать Canvas.itemconfig без каких-либо аргументов, кроме item (как указано выше), и это вернет словарь, содержащий все допустимые параметры для этого типа объекта холста и (среди прочего) текущее значение для этой опции.

Вторая часть проблемы оказалась намного проще, поскольку каждый из методов Canvas.create_* просто вызывает скрытый метод Canvas._create с координатами, kwargs и что самое интересное, тип объекта в виде строки. Например, вызов из Canvas.create_arc(*args, **kw) будет Canvas._create('arc', args, kw), что легко увидеть в tkinter source (ссылка ведет на то, что было последним blob-файлом на момент написания). Следовательно, если мы выполнили часть поиска правильно, эту часть будет очень просто реализовать.

* Если я что-то упустил, оставьте комментарий, я постараюсь исправить это.

Код

(для тех из нас, кому лень читать объяснение!)

Вот моя реализация приведенного выше объяснения:

import tkinter as tk

root = tk.Tk()
root.title("Canvas resume demo")
c = tk.Canvas(root, width=400, height=400)

# Create your canvas objects with some random coords and kwargs
c.create_rectangle(0, 0, 100, 100, fill="red", width=3)
c.create_line(0, 0, 100, 100)
c.create_polygon(90, 100, 100, 90, 100, 100, fill="blue")
# Items can also be deleted
c.delete(c.create_line(100, 100, 200, 200))

# Save the details into 'objs' (which can be pickle or json dumped)
objs = [(c.type(item),
            c.coords(item),
            {i: j[-1] for i, j in c.itemconfig(item).items()}) \
        for item in c.find_all()]

# Create a completely new canvas
c.destroy()
c = tk.Canvas(root, width=400, height=400)
c.pack()

# Resume from 'objs'
for item in objs:
    c._create(*item)

root.mainloop()

РЕДАКТИРОВАТЬ

Объекты Canvas, которые полагаются на другой объект tkinter (Canvas.create_image и Canvas.create_window), не будут правильно возобновлены при запуске в другом экземпляре (т.е. сохраненные данные а затем возобновить), так как эти объекты нужно будет повторно инициализировать с тем же именем Tcl. Для этого, вероятно, потребуется прочитать значение для соответствующих kwargs, а затем использовать комбинацию Misc.nametowidget и Misc.config, чтобы получить необходимую информацию.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...