Python在坐标处找不到tkinter项

时间:2019-12-19 01:20:10

标签: python tkinter mouse-coordinates

我有此代码:

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窗口。
  • 顶部的侏儒终端。

窗口堆叠顺序尚不完善,因为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小时后,我越来越近了。有必要从Window坐标(三个监视器的整个桌面)转换为canvas坐标(一个监视器上的一个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)

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

2 个答案:

答案 0 :(得分:1)

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

  

当前标签由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()

答案 1 :(得分: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_popup.post命令需要屏幕桌面坐标:(event.x_root, event.y_root)
  • .find_closest命令要求使用Canvas坐标:(event.x, event.y)