【问题标题】:What is the best way in Python to detect objects' ID being clicked with mouse?Python中检测对象ID被鼠标点击的最佳方法是什么?
【发布时间】:2020-12-27 20:15:57
【问题描述】:

我想问一下 Python 中与使用函数创建的画布对象交互的最佳方式是什么。
我的示例代码:

import tkinter
window = tkinter.Tk()
canvas = tkinter.Canvas(width=1000, height=600, bg="black")
canvas.pack()

def rectangle(x, y):
    canvas.create_rectangle(x, y, x + 5, y + 5, fill="white")

rect1 = rectangle(20, 50)
rect2 = rectangle(180, 30)
rect3 = rectangle(698, 322)
rect4 = rectangle(900, 66)
rect5 = rectangle(10, 506)
rect6 = rectangle(208, 455)

检测被鼠标点击的对象的 ID,然后在另一个函数中使用这些 ID 作为参数的最佳方法是什么?谢谢你的回答。

【问题讨论】:

  • 可以使用canvas.find_withtag("current")获取被点击的画布对象的item ID。

标签: python python-3.x tkinter canvas tkinter-canvas


【解决方案1】:

使用tag_bind

import tkinter
from functools import partial

window = tkinter.Tk()
canvas = tkinter.Canvas(width=1000, height=600, bg="black")
canvas.pack()

def on_click(item, event=None):
    print(f"Item id {item} was clicked!")

def rectangle(x, y):
    item_id = canvas.create_rectangle(x, y, x + 5, y + 5, fill="white")
    canvas.tag_bind(item_id, '<Button-1>', partial(on_click, item_id))

rect1 = rectangle(20, 50)
rect2 = rectangle(180, 30)
rect3 = rectangle(698, 322)
rect4 = rectangle(900, 66)
rect5 = rectangle(10, 506)
rect6 = rectangle(208, 455)

window.mainloop()

【讨论】:

  • 非常感谢,但是我想到是否可以将rect1rect2 等这些 ID 作为字符串变量的值(并最终打印或使用它们在代码的其他地方。
  • @bilykralik16 为此,一种方法可能是将变量 rect1 等存储到一个列表中,然后使用索引访问它们,如果您不打算将来实际使用这些对象,那么你还不如只存储一个对应每个字符串。
【解决方案2】:

画布有一个名为find_closest的方法,它将返回离光标最近的对象。

def highlight_nearest(event):
    canvas = event.widget
    x = canvas.canvasx(event.x)
    y = canvas.canvasy(event.y)
    item = canvas.find_closest(x, y)
    canvas.itemconfigure(item, fill="red")

canvas.bind("<1>", highlight_nearest)

find_closest 方法采用 x 和 y 坐标,以及可选的 halostart 参数。

这是the official documentation 不得不说的:

选择最接近由 xy 给出的点的项目。如果多个项目处于相同的最近距离(例如,两个项目与该点重叠),则使用这些项目中最顶部的项目(显示列表中的最后一个)。如果指定了 halo,则它必须是非负值。任何比光晕更接近该点的项目都被认为与该点重叠。 start 参数可用于循环遍历所有最近的项目。如果指定了 start,它使用标签或 id 命名一个项目(如果按标签,它选择显示列表中具有给定标签的第一个项目)。此表单将选择显示列表中 start 下方的最顶部最接近的项目,而不是选择最靠近的项目;如果不存在这样的项目,则选择的行为就像没有指定 start 参数一样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 2010-09-13
    • 1970-01-01
    • 2020-04-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多