右键单击菜单在远离单击位置的地方打开



我有一个画布。当我右键点击它时:

  1. 它会返回我点击的coords,没关系
  2. 打开带有一些功能的弹出菜单,但距离较远(左上(,这是主要问题。这不好

我希望此菜单在我刚刚右键单击的位置旁边打开(从鼠标单击的位置向上(。

我应该如何指定在哪里打开这个菜单,或者我可能需要更改一些属性?

from tkinter import *
from tkinter import ttk # for Treeview

class Main(Frame):
def __init__(self, main):
Frame.__init__(self, main)
# Vars that will be defined by user:
self.frame_width = 300
self.frame_height = 300
self.canvas_width = 600
self.canvas_height = 600
# Flexible widgets when window size alters:
main.columnconfigure(0, weight=1)
main.rowconfigure(0, weight=1)
# Some text
Label(text='Some text 1').grid(row=0, column=0)
Label(text='Some text 2').grid(row=1, column=0)
Label(text='Some text 3').grid(row=2, column=0)
Label(text='Some text 4').grid(row=3, column=0)
Label(text='Some text 5').grid(row=4, column=0)
# Canvas and frame
canvas_frame = Frame(main, width=self.frame_width, height=self.frame_height, relief='groove')
canvas_frame.grid(row=1, column=1)
canvas_frame.grid_propagate(False)
self.canvas = Canvas(canvas_frame, width = self.canvas_width, height = self.canvas_height,
bg='bisque')
self.canvas.grid(row=0, column=0)
# (!!!) RIGHT CLICK MENU
self.rmenu = Menu(self.canvas, tearoff=0, takefocus=0)
self.rmenu.add_command(label='Add', command=self.hello)
self.canvas.bind("<ButtonPress-3>", self.popup)
# Bind
self.canvas.bind("<ButtonPress-1>", self.scroll_start)
self.canvas.bind("<B1-Motion>", self.scroll_move)
# Functions
self.grid(self.canvas)
# End of init function.

# canvas popup menu: --------------------------------------------------
# (!!!) HERE IS THE POPUP RIGHTCLICK MENU FUNCTIONS
def popup(self, event):
self.rmenu.tk_popup(event.x + 40, event.y + 10, entry="0")
coords_1 = []
coords_1 += [[event.x, event.y]]
print(coords_1)
def hello(self):
print('hello')
# grid:  --------------------------------------------------
def grid(self, canvas):
for l in range(0, self.canvas_width, 10):
canvas.create_line([(l, 0), (l, self.canvas_width)], fill='#d9d9d9')
for l in range(0, self.canvas_height, 10):
canvas.create_line([(0, l), (self.canvas_height, l)], fill='#d9d9d9')
# scrolling canvas: ----------------------------------------
def scroll_start(self, event):
self.canvas.scan_mark(event.x, event.y)
def scroll_move(self, event):
self.canvas.scan_dragto(event.x, event.y, gain=1)

if __name__ == '__main__':
main = Tk()
# Making window opens in the centre of the screen
w = 800
h = 650
ws = main.winfo_screenwidth()
hs = main.winfo_screenheight()
x = (ws / 2) - (w / 2)
y = (hs / 2) - (h / 2)
main.geometry('%dx%d+%d+%d' % (800, 600, x, y))
#
Main(main)
main.mainloop()

我用(!!(和大写文本指出的所有必要部分

使用event.x_rootevent.y_root而不是event.xevent.y来获得绝对屏幕坐标。

self.rmenu.tk_popup(event.x_root + 40, event.y_root + 10, entry="0")

文档:事件和绑定


BTW:还有

x = root.winfo_pointerx()
y = root.winfo_pointery()

其还提供鼠标的绝对屏幕坐标。

(堆栈溢出:鼠标位置Python Tkinter(

只使用self.rmenu.tk_popup(event.x_root, event.y_root, entry="0"),而不是self.rmenu.tk_popup(event.x + 40, event.y + 10, entry="0")。这就是bug。菜单需要绝对的指针位置,而event.x、event.y是相对的。希望有帮助!

最新更新