Python Forum

Full Version: Draw a grid of Tkinter Canvas Rectangles
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello there.

I am back with another question. I am trying to draw a grid of tkinter Canvas Rects. Width and Length was specified in an earlier part of the program. Here is my code:

for x in range(wid):
        for y in range(leng):
            drawCanv.create_rectangle(x, y, leng/30, wid/30, outline='black')
However, I am only getting a completely black filled square in the top left corner of the Canvas.

Does anyone know what is wrong. I tried messing around with the fill, and when I change it to 'white', there is only 1 visible triangle with a black border, and white fill.
Are you able to supply a minimal example of runnable code that shows the problem at hand?
Sure:
#nam: name of project
#wid: width
#leng: length
#imports: import directory
#exports: export directory
#importFiles: files that have been imported

def editor(nam, wid, leng, imports, exports, directory, importFiles):

    widthLines = int(wid) - 1
    lengthLines = int(leng) - 1

    editor = Tk()
    editor.title("Editing "+nam)
    editor.geometry("800x700")

    nameLBL = Label(editor, text=nam, font=("Arial", 15)).pack()
    drawCanv = Canvas(editor, bg='white', width=800, height=500)
    drawCanv.pack()
    
    wid = int(wid)
    leng = int(leng)

    for x in range(wid):
        for y in range(leng):
            drawCanv.create_rectangle(x, y, x+30, y+30, outline='black')
That is still not runnable but when you create rectangles you have not taken into account their width and height.
the first is placed at 0,0 the next at 0, 1 if the width is 30 the next should be at 0, 31 etc.

you can use the step parameter of range
    for x in range(0, wid, 30):
        for y in range(0, leng, 30):
            drawCanv.create_rectangle(x, y, x+30, y+30, outline='black')
Thanks.
for example code run include imports and a snip it so others can easily copy and paste and run it.
Since canvas objects require exact coordinates the matrix style of two loops my not be the easiest way to accomplish what you want. If you are using buttons or labels it would.(by using the grid placement). I also suggest buttons, here's an example replace the text with a stock image maybe grass or sand, then when the button is pressed you give the user options to modify it.
from tkinter import Frame,Canvas,Tk,Button
from functools import partial

class Canvas_Grid(Frame):
    def __init__(self, parent= None,row=8,column=6):
        self.parent= parent
        self.parent.title('Canvas Grid 101')
        Frame.__init__(self, self.parent)
        self.pack(expand='yes',fill='both')
        self.canvas= Canvas(self)
        self.canvas.config(width=1000,height=600,bg='red')
        self.canvas.pack(expand='yes',fill='both')
        self.ROWS=row
        self.COLUMNS=column
        self.btns_list=[]
        for r in range(0,self.ROWS):            
            for c in range(0,self.COLUMNS):
                text_= 'r:{},c:{}'.format(r,c)
                self.btns_list.append(Button(self.canvas,text=text_,
                                             command=partial(self.update_pic,r,c))
                                      )
                self.btns_list[-1].grid(row=r,column=c,padx=1,pady=1)
    def update_pic(self,row,col):
        print('row:{} column:{}'.format(row,col))
                
if __name__ == '__main__':
    root= Tk()
    cg=Canvas_Grid(root,row=10,column=10)
    root.mainloop()