开发者

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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜