[英]Stardand context menu in Python TKinter text widget when mouse right button is pressed
I'm working on Windows XP, with Python 2.6.x and TKinter.我正在使用 Python 2.6.x 和 TKinter 在 Windows XP 上工作。 Using a text widget in the app, but the standard popup menu (cut, copy, paste, delete, select all) is missing.在应用程序中使用文本小部件,但缺少标准弹出菜单(剪切、复制、粘贴、删除、全选)。 How to make it appear?如何让它出现?
I found a way, thanks to this post .我找到了一种方法,感谢这篇文章。 I made some modifications.我做了一些修改。 At the bottom part there's a minimal main
to try it.在底部有一个最小的main
尝试。
from Tkinter import *
def rClicker(e):
''' right click context menu for all Tk Entry and Text widgets
'''
try:
def rClick_Copy(e, apnd=0):
e.widget.event_generate('<Control-c>')
def rClick_Cut(e):
e.widget.event_generate('<Control-x>')
def rClick_Paste(e):
e.widget.event_generate('<Control-v>')
e.widget.focus()
nclst=[
(' Cut', lambda e=e: rClick_Cut(e)),
(' Copy', lambda e=e: rClick_Copy(e)),
(' Paste', lambda e=e: rClick_Paste(e)),
]
rmenu = Menu(None, tearoff=0, takefocus=0)
for (txt, cmd) in nclst:
rmenu.add_command(label=txt, command=cmd)
rmenu.tk_popup(e.x_root+40, e.y_root+10,entry="0")
except TclError:
print ' - rClick menu, something wrong'
pass
return "break"
def rClickbinder(r):
try:
for b in [ 'Text', 'Entry', 'Listbox', 'Label']: #
r.bind_class(b, sequence='<Button-3>',
func=rClicker, add='')
except TclError:
print ' - rClickbinder, something wrong'
pass
if __name__ == '__main__':
master = Tk()
ent = Entry(master, width=50)
ent.pack(anchor="w")
#bind context menu to a specific element
ent.bind('<Button-3>',rClicker, add='')
#or bind it to any Text/Entry/Listbox/Label element
#rClickbinder(master)
master.mainloop()
Thought I would share my solution, based on several code snippets on stackoverflow.基于stackoverflow上的几个代码片段,我想我会分享我的解决方案。 It includes a minimum application to test:它包括一个最低限度的测试应用程序:
edit: class bindings might not work.编辑:类绑定可能不起作用。 Should that be the case use normal bindings and return "break" in the select_all functions.如果是这种情况,请使用普通绑定并在 select_all 函数中返回“break”。
import Tkinter as tk
if 1: # nice widgets
import ttk
else:
ttk = tk
class EntryPlus(ttk.Entry):
def __init__(self, *args, **kwargs):
ttk.Entry.__init__(self, *args, **kwargs)
_rc_menu_install(self)
# overwrite default class binding so we don't need to return "break"
self.bind_class("Entry", "<Control-a>", self.event_select_all)
self.bind("<Button-3><ButtonRelease-3>", self.show_menu)
def event_select_all(self, *args):
self.focus_force()
self.selection_range(0, tk.END)
def show_menu(self, e):
self.tk.call("tk_popup", self.menu, e.x_root, e.y_root)
class TextPlus(tk.Text):
def __init__(self, *args, **kwargs):
tk.Text.__init__(self, *args, **kwargs)
_rc_menu_install(self)
# overwrite default class binding so we don't need to return "break"
self.bind_class("Text", "<Control-a>", self.event_select_all)
self.bind("<Button-3><ButtonRelease-3>", self.show_menu)
def event_select_all(self, *args):
self.focus_force()
self.tag_add("sel","1.0","end")
def show_menu(self, e):
self.tk.call("tk_popup", self.menu, e.x_root, e.y_root)
def _rc_menu_install(w):
w.menu = tk.Menu(w, tearoff=0)
w.menu.add_command(label="Cut")
w.menu.add_command(label="Copy")
w.menu.add_command(label="Paste")
w.menu.add_separator()
w.menu.add_command(label="Select all")
w.menu.entryconfigure("Cut", command=lambda: w.focus_force() or w.event_generate("<<Cut>>"))
w.menu.entryconfigure("Copy", command=lambda: w.focus_force() or w.event_generate("<<Copy>>"))
w.menu.entryconfigure("Paste", command=lambda: w.focus_force() or w.event_generate("<<Paste>>"))
w.menu.entryconfigure("Select all", command=w.event_select_all)
if __name__ == "__main__":
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.entry = EntryPlus(self)
self.text = TextPlus(self)
self.entry.pack()
self.text.pack()
self.entry.insert(0, "copy paste")
self.text.insert(tk.INSERT, "copy paste")
app = SampleApp()
app.mainloop()
Thanks to Gonzo's code and bluish '<Control-c>',
my textwidget right button worked.感谢 Gonzo 的代码和蓝色'<Control-c>',
我的 textwidget 右键可以正常工作。 I don't have 50 reputations but I had a problem which I faced that the right button will trigger the function regardless of the location of the point clicked.我没有 50 名声望,但我遇到了一个问题,即无论点击的位置如何,右键都会触发该功能。 figured that out by:通过以下方式得出结论:
def show_menu(self, e):
if e.widget==self.text:
self.tk.call("tk_popup", self.menu, e.x_root, e.y_root)
Now only the right button's popup will be triggered when you click on text widget.现在,当您单击文本小部件时,只会触发右侧按钮的弹出窗口。
To add function that deletes selected text in tkinter text widget, use:要添加删除 tkinter 文本小部件中选定文本的功能,请使用:
def delete_highlighted_text():
text_widget.event_generate("<Delete>")
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.