简体   繁体   中英

tkinter canvas stays minimized

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

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()

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()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM