How to correctly use tkinter create_line() coordinates

27,873

You make mistake in second line

  • Python counts from 0 so left bottom corner is (0,2), not (0,3). So you have to start second line in point (0,2)

  • First line has points (0,0), (1,1), (2,2) and (3,3) which is outside of canvas. Similar second line should have (0,2), (1,1), (2,0) and (3,-1) which is outside of canvas. But you can't skip (3,3) and (3,-1) because create_line doesn't draw last point - last point doesn't belong to line (similar like x doesn't belong to range(x)). If you skip (3,3) and (3,-1) then create_line doesn't draw (2,2) and (2,0)

Correct lines

canvas.create_line(0,0,3,3, fill="red")
canvas.create_line(0,2,3,-1, fill="red")

in other words

  • first line (a,b,a+3,b+3) gives (0,0,0+3,0+3) = (0,0,3,3)
  • second line (a,b,a-3,b-3) gives (0,2,0-3,2-3) = (0,2,3,-1)
Share:
27,873
Admin
Author by

Admin

Updated on July 09, 2022

Comments

  • Admin
    Admin almost 2 years

    This tutorial is using the size of the canvas as coordinates for the lines: http://effbot.org/tkinterbook/canvas.htm

    However, if we edit the code to give the canvas no padding, we can see that this is not working correctly. If you look closely the second create_line() is not lining up with the corners correctly:

    from tkinter import *
    
    master = Tk()
    
    w = Canvas(master, width=200, height=100,bd=0,highlightthickness=0)
    w.configure(bg="black")
    w.pack()
    
    w.create_line(0, 0, 200, 100, fill="red")
    w.create_line(0, 100, 200, 0, fill="red")
    master.mainloop()
    

    Another example with a 3x3 canvas:

    from tkinter import *
    
    root = Tk()
    root.configure(bg="blue")
    canvas = Canvas(root, width=3, height=3, borderwidth=0, highlightthickness=0, bg="black")
    canvas.pack()
    
    canvas.create_line(0,0,3,3, fill="red")
    canvas.create_line(0,3,3,0, fill="red")
    
    root.mainloop()
    

    This problem seems to only effect lines going from bottom-left to top-right, or top-right to bottom-left.

    If we change the coordinates of the second create_line() to -1 and 3 it now works correctly:

    from tkinter import *
    
    root = Tk()
    root.configure(bg="blue")
    canvas = Canvas(root, width=3, height=3, borderwidth=0, highlightthickness=0, bg="black")
    canvas.pack()
    
    canvas.create_line(0,0,3,3, fill="red")
    canvas.create_line(-1,3,3,-1, fill="red")
    
    root.mainloop()
    

    My questions are: Why does this only effect the second create_line()? Why does the coordinate 0 become -1, if 3 does not become 2? Is this the way it's supposed to work, or does tkinter just have an inherent problem with drawing positive slopes correctly? It seems to me that the latter is the case. If I want to make a program that draws many lines based on a given set of coordinates, I would seemingly have to calculate if every given segment is a positive or negative slope before creating it.

    I have had to put the program I'm making on a complete hold for several days because of this. Can somebody please provide any insight to this issue? Is there something I am missing or not understanding?

    • furas
      furas over 7 years
      Canvas 3x3 is too small for me so I don't see the problem. On bigger canvas I don't see problem too. Maybe I use different system (Linux) then you or I don't care about this detail.
    • Admin
      Admin over 7 years
      I'm only using the canvas size to show that create_line() is reaching the wrong coordinates, but it has nothing to do with the canvas.The lines should reach the corner pixels of the canvas, creating an "X". It's off by a single pixel so it's hard to see if you're using high resolution. It's the same problem with any size canvas. Here is a zoomed in screenshot: imgur.com/a/hJnrQ