51

I've been messing with the Tkinter Canvas widget in order to see if I could make some aesthetically pleasing widgets, and I have a few questions.

First, why is there a light grey border around my Canvas widget, and how do I get rid of it?

Secondly, why is the top left most position in the Canvas (2,2)? It seems like it should be (0,0).

My current script:

from Tkinter import *

master = Tk()
master.configure(bg='black')
master.wm_attributes("-topmost", 1)

w = Canvas(master, width=150, height=40, bd=0,relief='ridge',)
w.pack()

color = 100
x0 = 2
y0 = 2
x1 = 151
y1 = 2

while y0 < 20 :
    r = color
    g = color
    b = color
    rgb = r, g, b
    Hex = '#%02x%02x%02x' % rgb
    w.create_line(x0, y0, x1, y1,fill=str(Hex), width=1)
    color = color - 2
    y0 = y0 + 1
    y1 = y1 + 1

color = 10

while y0 < 40 :
    r = color
    g = color
    b = color
    rgb = r, g, b
    Hex = '#%02x%02x%02x' % rgb
    w.create_line(x0, y0, x1, y1,fill=str(Hex), width=1)
    color = color + 4
    y0 = y0 + 1
    y1 = y1 + 1

mainloop()
Laurel
  • 5,965
  • 14
  • 31
  • 57
rectangletangle
  • 50,393
  • 94
  • 205
  • 275

3 Answers3

90

Section 6.8 Why doesn't the canvas seem to start at 0,0? of the Tk Usage FAQ describes the phenomenon.

I was able to eliminate the border artefact with slight changes to the posted source...

Change this:

w = Canvas(master, width=150, height=40, bd=0, relief='ridge')
w.pack()

to:

w = Canvas(master, width=150, height=40, bd=0, highlightthickness=0, relief='ridge')
w.pack()

and this:

x0 = 2
y0 = 2
x1 = 151
y1 = 2

to:

x0 = 0
y0 = 0
x1 = 150
y1 = 0

Interestingly enough, the "borderwidth" attribute did not make a difference, but I left it in per the FAQ.

Running w.config() immediately after the Canvas initialization statement showed the defaults to be 2 for highlightthickness and 0 for border width.

sergiol
  • 4,122
  • 4
  • 47
  • 81
T.P.
  • 2,975
  • 1
  • 21
  • 20
  • Thanks, that killed two birds with one stone! – rectangletangle Nov 30 '10 at 07:09
  • 4
    The `borderwidth` config didn't make a difference because the original code was already setting the border width to zero with the `bd` option, which is a synonym for `borderwidth` – Bryan Oakley Nov 30 '10 at 11:53
  • 2
    what do you mean by "All indicators infer that Tk Canvas is borked to a degree"? THe canvas is a terrific widget, what indicators say it is borked? – Bryan Oakley Nov 30 '10 at 11:54
  • @Bryan - For me neither the borderwidth option nor its abbreviated form made a difference for this particular case. Setting the highlightthickness option alone removed the 2-pixel gray border. To check, I removed both the borderwidth and highlightthickness attributes and ran w.config(). "highlightthickness" defaulted to 2, while "borderwidth" defaulted to 0. Is there any possibility the defaults are platform specific? Anyway, I edited the response to simplify. And yes, the Canvas is a great widget. Removed the first statement as well so as not to mislead anyone. – T.P. Nov 30 '10 at 13:18
  • yes, defaults can not only be platform-specific, but window-manager specific and user-specific. – Bryan Oakley Nov 30 '10 at 21:28
  • Thank you so much for highlightthickness, I was going mad. – boztalay Sep 04 '14 at 16:35
  • Your answer gave me the reason of my problem: https://codegolf.stackexchange.com/questions/85141/draw-the-national-flag-of-iceland/131490#comment346671_131490 — I finally discovered the origin of the "stupid margin"; the highlightthickness attribute of canvas is by default 2 (instead of 0) – sergiol Dec 04 '17 at 15:26
21

The short answer is, the Canvas has two components which affect the edges: the border (borderwidth attribute) and highlight ring (highlightthickness attribute).

If you have a border width of zero and a highlight thickness of zero, the canvas coordinates will begin at 0,0. Otherwise, these two components of the canvas infringe upon the coordinate space.

What I most often do is set these attributes to zero. Then, if I actually want a border I'll put that canvas inside a frame and give the frame a border.

nbro
  • 15,395
  • 32
  • 113
  • 196
Bryan Oakley
  • 370,779
  • 53
  • 539
  • 685
0

If adding highlightthickness in the canvas class instance throws an error (it was recently doing for me). Add it in config as shown below:

canvas=Canvas(width=206,height=260, bg=YELLOW)
canvas.config(highlightthickness=0)
Manish
  • 501
  • 4
  • 5