如何让画布真正具有尺寸?
root = Tk()
canv = Canvas(root, width=600, height=600)
canv.pack(fill = BOTH, expand = True)
root.after(1, draw)
mainloop()
只需在左上角创建一个带有1px画布的窗口
编辑:我省略了绘图,因为它没有抛出任何东西,因此似乎没有相关性。但是,如果我通过pdb通过它完美运行,这里是完整的代码:
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()
操作系统是ubuntu 16.04, python版本是预装的python3,通过终端
运行答案 0 :(得分:2)
你的画布没有保持最小化。如果你给画布一个明显的背景颜色,你会发现它会立即填满整个窗口,并保持这种状态。
你得到1
的窗口宽度和高度,因为你没有给tkinter足够的时间来绘制它,然后再询问尺寸。 winfo_width
和winfo_height
会返回实际高度,并且无法计算实际高度,直到窗口在屏幕上实际可见。
最简单的解决方案是在调用init
函数之前强制更新。您可以致电update
,然后拨打init
而不是使用after
来执行此操作。
而不是:
root.after(1, init)
这样做:
root.update()
init()
答案 1 :(得分:1)
我能够让你的画布显示并正常工作。您的init
功能似乎就是问题所在。你不需要定义一个等待的时间来调用你的init()函数直接调用它,程序将完成剩下的工作。
此外,我查看了画布的tkinter文档,我没有看到像.draw()
这样的内容。我认为tkinter不存在类似的函数。我可能错了,但如果确实存在,则文档不明显。
改为使用:
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()