Reputation: 19
I have search for hours on the net how to delete and next recreate a "canvas" on Tkinter.
So first my code :
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()
I just want to create a grid and when an element in the matrix changes the grid changes too (0 = white and 1 = black) In my case i use
canvas.destroy()
to clear the window
and i wait 0.5 seconds with time.sleep() until i show the new image from the matrix
My problem is that i can't see the actualization :(
I just see the last frame ! I don't know if it is the canvas.pack() or something like that which can not be refreshed.
NB : This is a simplification for a bigger plan !
NB 2 : Sorry for my weird english i'm french you know...
THANK YOU
Upvotes: 1
Views: 3605
Reputation: 1279
There are obviously two parts to this question:
For the first part of the problem, I believe there are a further three parts that need to be considered*, which are as follows:
Canvas.type
method which we can use.Canvas.coords
and what the tkinter documentation doesn't explain is that if this method is called without any coords (only the item
is provided), it will return the current coords of the given item (rather than changing them).Canvas.itemconfig
without any arguments other than the item
(like above), and this will return a dictionary containing all valid options for that type of canvas object and (among other things) the current value for that option.The second part of the problem turned out to be much simpler as each of the Canvas.create_*
methods simply calls the hidden method Canvas._create
with the coords, kwargs and most interestingly, the object type as a string. For example, the call from Canvas.create_arc(*args, **kw)
is Canvas._create('arc', args, kw)
, as easily seen in the tkinter source (the link is to what was the latest blob at the time of writing). Therefore, if we have done the retrieval part correctly, this part should be very simple to implement.
*If I have overlooked something, please leave a comment I will try to address it.
(for those of us too lazy to read the explanation!)
Here is my implementation of the above explanation:
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()
EDIT
Canvas objects which rely on another tkinter object (Canvas.create_image
and Canvas.create_window
) will not resume correctly if run in different instance (i.e. details saved and then resumed) as these objects will need to be reinitialised with the same Tcl name. For this, would would probably need to read the value for the relevant kwargs and then use a combination of Misc.nametowidget
and Misc.config
to be able to get required information.
Upvotes: 1