The Tkinter pack manager tries to resize the parent widget to the correct size to contain the child widgets, and by default no more. Thus, the canvas is there, but it is exactly the same size as the button, and thus invisible.
If you want to place the widget on the canvas without causing the canvas to dynamically resize, you need the Canvas.create_window() function:
# ... snip ... button1 = Button(self, text = "Quit", command = self.quit, anchor = W) button1.configure(width = 10, activebackground = "#33B5E5", relief = FLAT) button1_window = canvas1.create_window(10, 10, anchor=NW, window=button1)
This will create your button with the upper left corner at (10, 10) relative to the canvas, without resizing the canvas itself.
Note that you can replace the window argument with a link to any other Tkinter widget. However, one caveat: the named widget must be a child of the top-level window containing the canvas, or a child of any widget located in the same top window.
source share