Python Tkinter continuous line with endpoints that don't match up
Basically I'm trying to create a continuous line (starting when the user clicks, ending when they right click), and I have it working, but for some reason the end points (ovals), don't really line up perfectly with the sides of the line (it becomes really obvious when you try drawing a straight line with multiple points or try right angles)... i've tried just about everything and am thoroughly frustrated so I posted here to see if you guys had any ideas..
Here's the code so you can try it out and see what i mean:
from Tkinter import *
class GUI:
def __init__(self,root):
Window = Frame(root)
self.DrawArea = Canvas(Window)
self.DrawArea.pack()
Window.pack()
self.linewidth = 20
self.DrawArea.config(cursor="crosshair")
self.DrawArea.bind("<Button 1>",self.startline)
def startline(self,event):
self.startx, self.starty = self.DrawArea.canvasx(event.x),self.DrawArea.canvasy(event.y)
xa,ya = self.startx-self.linewidth/2 , self.starty+self.linewidth/2
xb,yb = self.startx+self.linewidth/2 , self.starty-self.linewidth/2
self.StartPoint = self.DrawArea.create_oval(xa,ya,xb,yb,fill='red',outline='')
self.Line = None
self.EndPoint = None
self.DrawArea.bind("<Motion>"开发者_C百科,self.updateline)
self.DrawArea.bind("<Button 3>",self.killline)
def updateline(self,event):
if self.EndPoint: self.DrawArea.delete(self.EndPoint)
if self.Line: self.DrawArea.delete(self.Line)
x,y = self.DrawArea.canvasx(event.x),self.DrawArea.canvasy(event.y)
xa,ya = x-self.linewidth/2 , y+self.linewidth/2
xb,yb = x+self.linewidth/2 , y-self.linewidth/2
self.Line = self.DrawArea.create_line(self.startx,self.starty,x,y,fill='red',width=self.linewidth)
self.EndPoint = self.DrawArea.create_oval(xa,ya,xb,yb,fill='red',outline='')
def killline(self,event):
self.DrawArea.delete(self.Line)
self.DrawArea.delete(self.StartPoint)
self.DrawArea.delete(self.EndPoint)
self.DrawArea.unbind("<Motion>")
if __name__ == '__main__':
root = Tk()
root.title("Line Draw")
App = GUI(root)
root.mainloop()
Rather than draw circles at the end of lines, you can use the capstyle
and joinstyle
options of the line.
For example:
self.Line = self.DrawArea.create_line(self.startx,self.starty, x, y, fill='red',
width=self.linewidth, capstyle=ROUND, joinstyle=ROUND)
On my screen, and my version of Python (2.5 on Windows XP), the circles and lines fit together nicely if you use an odd number of pixels for the line width, at least for the widths that I've tried. I think this is because your coordinates are not ideal zero-dimensional points as in math, but rather correspond to pixels. So the minimal-width point or line is one-pixel wide. And that is where your cursor "lives". To make things thicker in a balanced way, you have to add the same number of pixels on either side of this minimal width; thus you must have an odd number of pixels for total width.
精彩评论