0

I'm trying to build a simple GUI in Tkinter and I'm having trouble with placing a frame and a canvas beside each other. The canvas seems to take up more space than the width and height that have been specified.

Example code:

root = tk.Tk()
parent = tk.Frame(root)
parent.grid()
parent.master.geometry('400x400')
canvas = tk.Canvas(parent, width=200, height=400, relief='raised', borderwidth=5)
canvas.grid(row=0, column=0, sticky='nsew')
frame = tk.Frame(parent, width=200, height=400, relief='raised', borderwidth=5)
frame.grid(row=0, column=1, sticky='nsew')
parent.mainloop()

This gives this result:

Canvas and Frame in same window

You can see that the canvas has pushed the frame outside the window

However, when its just the frame, the frame fits nicely within the window:

enter image description here

When it's just the canvas the canvas pushes outside the window:

enter image description here

What is causing this difference in sizing and how do I handle it? Is there a proper way to set the size of a canvas?

BeanBagTheCat
  • 435
  • 4
  • 7
  • 1
    The borderwidth you specifying is taking extra space. In addition there is an option called *highlightthickness* which also takes a bit space. An easier way of doing what you want would be to use pack for these containers and call pack_propagate to the parent while using the options *fill* and *side* of the pack method. [For more information](https://stackoverflow.com/questions/63536505/how-do-i-organize-my-tkinter-appllication/63536506#63536506) – Thingamabobs Oct 05 '21 at 17:39
  • @Atlas435 So the canvases borderwidth affects the overall width of the widget but the frame doesnt behave the same way? Interesting! Is there any way to do this neatly with grid or is pack the only way? The rest of the GUI is using grid right now. – BeanBagTheCat Oct 05 '21 at 17:41
  • 1
    you don't need to stick to a geometry manager in your whole GUI. It's just important to use either pack or grid in a specific master(window/frame). As I can see it would be the easiest way to implement your design. If you really want to stick with grid you can do this. – Thingamabobs Oct 05 '21 at 17:46
  • @Atlas435 Oh okay perfect! I misunderstood the geometry manager caveats. I thought you needed to use the same one throughout. Thank you for your answer! – BeanBagTheCat Oct 05 '21 at 17:48
  • 1
    try using `Canvas(... ,highlightthickness=0)` but the borderwidth will still consume extra space you need to calculate. – Thingamabobs Oct 05 '21 at 17:50

1 Answers1

1

In addition to the width parameter, there are two other parameters that control the width of a canvas: borderwidth and highlightthickness. Both of those may have non-zero default values, depending on your platform.

In addition, the geometry manager may also contribute to the width and height depending on options and other factors.

To get a canvas that is precisely 200 pixels wide and 400 pixels tall, set the other values to zero, and don't use geometry manager options that may restrict or expand the size of the widget.

canvas = tk.Canvas(root, width=200, height=400, borderwidth=0, highlilghtthickness=0)
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685