Tkinter Sucks Tkinter Sucks - 1 month ago 15
Python Question

How to correctly use tkinter create_line() coordinates

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?

Answer

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)
Comments