В основном, я пытаюсь создать непрерывную линию (начиная с того, когда пользователь нажимает, заканчивая, когда они нажимают правой кнопкой мыши), и у меня есть работа, но по какой-то причине конечные точки (овалы) не очень хорошо выстраиваются (это становится действительно очевидным, когда вы пытаетесь рисовать прямую линию с несколькими точками или пытаться под прямым углом)... Я пробовал практически все и полностью расстроен, поэтому я разместил здесь, чтобы узнать, есть ли у вас какие-либо идеи..
Вот код, чтобы вы могли попробовать и посмотреть, что я имею в виду:
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>",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()
Вместо рисования кругов в конце строк вы можете использовать capstyle
и joinstyle
линии.
Например:
self.Line = self.DrawArea.create_line(self.startx,self.starty, x, y, fill='red',
width=self.linewidth, capstyle=ROUND, joinstyle=ROUND)
На моем экране и моей версии Python (2.5 на Windows XP) круги и строки прекрасно сочетаются, если вы используете нечетное количество пикселей для ширины линии, по крайней мере, для ширины, которые я пробовал. Я думаю, это потому, что ваши координаты не являются идеальными нульмерными точками, как в математике, а скорее соответствуют пикселям. Таким образом, точка или линия минимальной ширины имеют ширину в один пиксель. И вот где ваш курсор "живет". Чтобы сделать вещи более толстыми сбалансированным образом, вы должны добавить одинаковое количество пикселей по обе стороны от этой минимальной ширины; таким образом, вы должны иметь нечетное количество пикселей для общей ширины.