Reputation: 191
how do I get a canvas to actually have a size?
root = Tk()
canv = Canvas(root, width=600, height=600)
canv.pack(fill = BOTH, expand = True)
root.after(1, draw)
mainloop()
just creates a window with a 1px canvas in the top left corner
edit: I omitted draw, because it didn’t throw anything, thus didn’t seem relevant. But since it runs perfectly if I n through it via pdb, here’s the full code:
from tkinter import *
from pdb import set_trace
class Field: #abstact
def __init__(self, size):
super().__init__()
self.tiles = [[(None, 0) for i in range(size[1])] for j in range(size[0])] #list of columns
def get_tile(self, x,y):
return tiles[x][y]
def inc_tile(self, x,y,player):
t = self.tiles[x][y]
tiles[x][y] = (player, t[1])
class RectField(Field):
def __init__(self, size):
super().__init__(size)
def select_tile(self, x, y):
lx = len(self.tiles)
rx = floor(x*lx)
ly = len(self.tiles[rx])
ry = floor(x*ly)
return (rx, ry)
def draw(self, canvas):
canvas.delete(ALL)
w = canvas.winfo_width()
h = canvas.winfo_height()
canvas.create_rectangle(0, 0, w, h, fill='#f0f')
sx = w/len(self.tiles)
for i in range(len(self.tiles)):
sy = h/len(self.tiles[i])
for j in range(len(self.tiles[i])):
pl = self.tiles[i][j][0]
cl = '#888' if not pl else ('#f20' if pl == 1 else '#02f')
canvas.create_rectangle(i*sx, j*sy, (i+1)*sx, (j+1)*sy, fill=cl, outline='#000')
############################################################################## #####################
# MAIN
############################################################################## #####################
root = Tk()
canv = Canvas(root, width=600, height=600)
canv.pack(fill = BOTH, expand = True)
#set_trace()
field = RectField((4,4))
def init():
canv.create_rectangle(0, 0, 600, 600, fill='#f0f')
set_trace()
field.draw(canv)
root.update()
root.after(1, init)
mainloop()
OS is ubuntu 16.04, python version is the preinstalled python3, run via terminal
Upvotes: 1
Views: 209
Reputation: 15226
I was able to get your canvas to show up and work fine. It looks like your init
function was the problem. You don't need to define a time to wait when calling your init() function just call it directly and the program will do the rest.
Also I have looked over the tkinter documentation for canvas and I do not see anything like .draw()
I do not think a function like that exist for tkinter. I could be wrong but if it does exist the documentation is not obvious.
use this instead:
def init():
canv.create_rectangle(0, 0, 600, 600, fill='blue')
# I only changed the color to make sure it was working
#set_trace() # not needed.
#field.draw(canv) # does nothing?
#root.update() # not needed in this case.
init()
Upvotes: 1
Reputation: 385940
Your canvas is not staying minimized. If you were to give the canvas a distinct background color you would see that it immediately fills the whole window, and stays that way.
You are getting 1
for the window width and height because you aren't giving tkinter enough time to draw it before asking for the size. winfo_width
and winfo_height
return the actual height, and the actual height can't be computed until the window is actually visible on the screen.
The simplest solution is to force an update before calling your init
function. You can do this by calling update
and then calling init
rather than using after
.
Instead of this:
root.after(1, init)
Do this:
root.update()
init()
Upvotes: 2