0

我有这个代码:

for item in items:
    print ( "Item: ", item, mycanvas.coords (item) )

print ("Item at 26.0, 188.0 ", mycanvas.find_closest(26.0, 188.0))
print ("Item at 998.0, 594.0 ", mycanvas.find_closest(998.0, 594.0))

当我运行它时,我得到:

('Item: ', 1, [985.0, 565.0])
('Item: ', 8, [25.0, 25.0])
('Item: ', 15, [505.0, 25.0])
('Item: ', 28, [1362.0, 31.0])
('Item: ', 35, [1020.0, 119.0])
('Item: ', 42, [1050.0, 583.0])
('Item: ', 49, [25.0, 25.0])
('Item: ', 56, [26.0, 188.0])
('Item: ', 63, [998.0, 594.0])
('Item: ', 70, [1152.0, 38.0])
('Item at 26.0, 188.0 ', (57,))
('Item at 998.0, 594.0 ', (64,))

最后两行应分别读取项目5663找到。

我在屏幕上有 10 张图片,我试图找出点击的是哪一张。更糟糕的是 X,Y 坐标被传递给屏幕位置而不是画布位置,我必须弄清楚如何转换:

def popup(event):
    x = mycanvas.canvasx(event.x_root)
    y = mycanvas.canvasy(event.y_root)
    print( "Adjusted x, y: ", x, y )
    FoundItem=mycanvas.find_closest(x, y)
    print( "Found Item @ x, y: ", FoundItem, event.x_root, event.y_root )
    FoundTuple=mycanvas.find_overlapping(x, y, x+1, y+1)
    print( "Found Tuple: ", FoundTuple )
    # use coordinates relative to the canvas
#    ItemNdx=items.index(FoundItem)
#    print( "ItemNdx: ", ItemNdx )
    menu.tk_popup(event.x_root, event.y_root)

在 Python 的 Tkinter 中,找出用户点击了哪个图像(项目/标签 ID)的最简单方法是什么?


带有窗口图像的监视器图像

要了解画布的外观:

wman2 edp-1-1.png

这是三个显示器 eDP-1-1 之一的部分。在最坏的情况下,有四个窗口打开:

  • gedit有问题的源代码在底部打开。
  • 带有此问答的 Firefox 浏览器在上面打开。
  • Nautilus 窗户在上面。
  • 顶部的 Gnome 终端。

窗口堆叠顺序还不是很完美,因为wmctrl它用于在桌面上获取所有打开的窗口,而无需按堆叠顺序进行任何排序。

所以用户会点击最接近他们想要选择的图像的左上角。用户也可以点击没有被窗口覆盖的空白监视器区域来选择监视器图像。- 带有本网站的 Firefox 浏览器

标签电流也是一关

我输入了这段代码:

tag_current=event.widget.find_withtag("current")
print ("tag_current: ", tag_current)

结果是这样的:

('Item: ', 1, [985.0, 565.0])
('Item: ', 8, [25.0, 25.0])
('Item: ', 15, [505.0, 25.0])
('Item: ', 28, [1362.0, 31.0])
('Item: ', 35, [949.0, 167.0])
('Item: ', 42, [1050.0, 583.0])
('Item: ', 49, [83.0, 52.0])
('Item: ', 56, [26.0, 188.0])
('Item: ', 63, [998.0, 594.0])
('Item: ', 70, [25.0, 25.0])
('Item: ', 77, [1091.0, 644.0])
('Item at 26.0, 188.0 ', (70,))
('Item at 998.0, 594.0 ', (64,))
('tag_current: ', (41,))

tag_current应该是42,但被报告为41

63报告6456正在报告的问题大致相同70(之前报告为57上次运行作业)。


12小时更新

12小时后,我越来越近了。需要将窗口坐标(三个显示器的整个桌面)转换为画布坐标(其中一个显示器上的一个 Python 程序):

def popup(event):
    global FoundItem, MouseXY
    x = mycanvas.canvasx(event.x)
    y = mycanvas.canvasy(event.y)
    MouseXY=(x, y)
    print( "Adjusted x, y: ", x, y )
    FoundItem=mycanvas.find_closest(x, y)

希望今晚能解决问题...

4

2 回答 2

1

找出“用户点击了哪个图像(标签/标签 ID)”的方法是使用标签current。规范的 tcl/tk 文档对当前标签进行了以下说明:

标签电流由 Tk 自动管理;它适用于 当前项目,它是绘制区域覆盖鼠标光标位置的最顶层项目(不同的项目类型以不同的方式解释这一点;有关详细信息,请参阅单个项目类型文档)。如果鼠标不在画布小部件中或不在项目上方,则没有项目具有当前标签。

这是一个人为的示例,它将打印出与您单击的任何项目相关联的标签。请注意,即使您滚动画布,它也可以工作。

import tkinter as tk

def callback(event):
    tags = canvas.itemcget("current", "tags")
    label.configure(text=f"you clicked on {tags}")

root = tk.Tk()
canvas = tk.Canvas(root, width=300, height=300)
label = tk.Label(root)
ysb = tk.Scrollbar(root, orient="vertical", command=canvas.yview)
xsb = tk.Scrollbar(root, orient="horizontal", command=canvas.xview)
canvas.configure(yscrollcommand=ysb.set, xscrollcommand=xsb.set)

root.grid_rowconfigure(0, weight=1)
root.grid_columnconfigure(0, weight=1)

canvas.grid(row=0, column=0, sticky="ew")
xsb.grid(row=1, column=0, sticky="ew")
ysb.grid(row=0, column=1, sticky="ns")
label.grid(row=2, columnspan=2, sticky="ew")

x = 10
y = 10
for color in ("red", "orange", "yellow", "green", "blue", "black", "bisque"):
    canvas.create_rectangle(x, y, x+100, y+100,
                            outline=color, fill=color,
                            tags=(color,)
    )
    x += 50
    y += 50
canvas.configure(scrollregion=canvas.bbox("all"))
canvas.bind("<Button-1>", callback)

root.mainloop()
于 2019-12-19T02:26:16.590 回答
0

这是使其工作的最终解决方案:

def popup(event):
    global FoundItem
#    print( "Root x, y: ", event.x_root, event.y_root )
#    print( "event x, y: ", event.x, event.y )
    FoundItem=mycanvas.find_closest(event.x, event.y)
    menu.tk_popup(event.x_root, event.y_root)

您可以删除注释(#字符)以查看x,y终端中的坐标。

  • .tk_popupor.post命令需要屏幕桌面坐标:(event.x_root, event.y_root)
  • .find_closest命令需要 Canvas 坐标:(event.x, event.y)
于 2019-12-21T15:34:03.870 回答