【问题标题】:Python Tkinter problem with looping to check if mouse clicked on line(canvas)Python Tkinter循环问题以检查鼠标是否单击了行(画布)
【发布时间】:2020-07-02 03:01:31
【问题描述】:

我想检查鼠标是否点击了 Tkinter 画布上的一行,如果在一行上,那么是哪一行。 我做了这个来检测鼠标点击。

class Link:
    def __init__(self,Node1,Node2,canvas,width=5):
        if self not in canvas.LinkList:
            self.start_coor = Node1.Centre
            self.final_coor = Node2.Centre
            self.Canvas = canvas
            self.Width = width
            self.Shape = canvas.create_line(self.start_coor,self.final_coor,width=width)
            Node1.connected(Node2)
            self.Canvas.LinkList.append(self)
            self.Nodes = [Node1,Node2]

            self.Clicked = False

            dy = self.final_coor[1] - self.start_coor[1]
            dx = self.final_coor[0] - self.start_coor[0]
            self.m = dy/dx
            self.c = self.start_coor[1] - self.m*self.start_coor[0]

    def onLineCheck(self,x,y,field=False):
        #y = mx + c
        #y - mx - c = 0
        if not field:
            field = self.Width
        if (x < self.start_coor[0] and x < self.final_coor[1]) or (x > self.start_coor[0] and x > self.final_coor[1]) or (y < self.start_coor[1] and y < self.final_coor[1]) or (y > self.start_coor[1] and y > self.final_coor[1]):
            return False
        temp =  y - (self.m*x) - self.c
        if abs(temp) <= field:
            return True
        return False
class InputCanvas(Canvas):

    def __init__(self,master=None, **kw):
        super().__init__(master,**kw)
        self.NodeList = []
        self.LinkList = []
        self.Mode = "Nodes"
    def anyLinkClicked(self,e):
        x,y = getMousePosition(e)
        for l in self.LinkList:
            if l.onLineCheck(x,y):
                return l
        return False

每次创建链接时,它都会自动将自己附加到canvas.LinkList。我确信这部分代码工作正常。 到目前为止,该程序在 Canvas 上的 1 行中运行良好(即使我将其删除并绘制新的它仍在工作)但不能处理超过 1 行,它只能响应创建的第一行。即使我删除了第一行,创建的第二行也不起作用。 我已经尝试打印出每个 onLineCheck() 的结果,看起来循环在每一行中都正确循环,但它没有捕捉到鼠标点击。 有什么好办法吗?

【问题讨论】:

标签: python canvas tkinter


【解决方案1】:

问题出在下面一行:

if (x < self.start_coor[0] and x < self.final_coor[1]) or (x > self.start_coor[0] and x > self.final_coor[1]) or (y < self.start_coor[1] and y < self.final_coor[1]) or (y > self.start_coor[1] and y > self.final_coor[1]):
    return False
  • x &lt; self.final_coor[1] 应该是 x &lt; self.final_coor[0]
  • x &gt; self.final_coor[1] 应该是 x &gt; self.final_coor[0]

您还应该满足垂直线,即dx 为零,因为您的代码将引发ZeroDivisionError: division by zero

您可以使用Canvas.find_overlapping() 函数查找点击了哪个Link

def anyLinkClicked(self, e):
    x, y = getMousePosition(e)
    found = self.find_overlapping(x, y, x, y)
    if found:
        for l in self.LinkList:
            if found[0] == l.Shape:
                return l
    return False

【讨论】:

  • 谢谢。这就是我一直在寻找的。​​span>
猜你喜欢
  • 2014-05-29
  • 2018-07-09
  • 1970-01-01
  • 2020-10-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多