问题
I'd like to make menu items (in the menubar, not in a right click pop-up window) that can cut/copy/paste whatever text is selected.
The equivalent keyboard commands already work without my having done anything to enable them. For example, I can enter text in an entry box, cut it with Control-X, and paste it back (or elsewhere) with Control-C.
The posts on the topic I've seen boil down to cut/copy/paste for individual widgets, but that already works. How do I make the menu items activate them?
Thanks.
EDIT: Just to be clear, The issues are:
- how to make the menu items for cut/copy act on whatever text is selected in any widget
- how to have the paste menu item paste text wherever the text cursor is
Again, the key commands to do this (Control-x, Control-c, Control-v) already work without my having done anything. I know how to make the menus; the question is just what command I should attach to the menu items to have the desired effect.
EDIT 2: Ok, I've got a way that works. Since the key commands already work, we can just generate them. In my case, everything is a a notebook named noteBook so
lambda: self.noteBook.event_generate('<Control-x>')
cuts as desired. For example:
editmenu.add_command(label="Cut", accelerator="Ctrl+X", command=lambda: self.noteBook.event_generate('<Control-x>'))
In use: https://github.com/lnmaurer/qubit-control-interface/commit/c08c10a7fbc4a637c1e08358fb9a8593dfdf116e
Still, there's probably a cleaner way to do this; please reply if you know it.
回答1:
try this: source
import Tkinter
def make_menu(w):
global the_menu
the_menu = Tkinter.Menu(w, tearoff=0)
the_menu.add_command(label="Cut")
the_menu.add_command(label="Copy")
the_menu.add_command(label="Paste")
def show_menu(e):
w = e.widget
the_menu.entryconfigure("Cut",
command=lambda: w.event_generate("<<Cut>>"))
the_menu.entryconfigure("Copy",
command=lambda: w.event_generate("<<Copy>>"))
the_menu.entryconfigure("Paste",
command=lambda: w.event_generate("<<Paste>>"))
the_menu.tk.call("tk_popup", the_menu, e.x_root, e.y_root)
t = Tkinter.Tk()
make_menu(t)
e1 = Tkinter.Entry(); e1.pack()
e2 = Tkinter.Entry(); e2.pack()
e1.bind_class("Entry", "<Button-3><ButtonRelease-3>", show_menu)
t.mainloop()
回答2:
Use the focus_get()
method to get the widget which currently has keyboard focus, and then send the event to that widget. E.g.
editmenu = Menu(menubar, tearoff=0)
editmenu.add_command(label="Cut", \
accelerator="Ctrl+X", \
command=lambda: \
mywindow.focus_get().event_generate('<<Cut>>'))
回答3:
Have Fun
from Tkinter import *
class Test(Text):
def __init__(self, master, **kw):
Text.__init__(self, master, **kw)
self.bind('<Control-c>', self.copy)
self.bind('<Control-x>', self.cut)
self.bind('<Control-v>', self.paste)
def copy(self, event=None):
self.clipboard_clear()
text = self.get("sel.first", "sel.last")
self.clipboard_append(text)
def cut(self, event):
self.copy()
self.delete("sel.first", "sel.last")
def paste(self, event):
text = self.selection_get(selection='CLIPBOARD')
self.insert('insert', text)
def test():
r = Tk()
t = Test(r)
t.pack(fill='both', expand=1)
r.mainloop()
if __name__ == '__main__':
test()
回答4:
I just came across your question nine months too late (does that make this a pregnant pause?). This code works for me:
editmenu = Menu(menubar, tearoff=0)
editmenu.add_command(label="Cut", \
accelerator="Ctrl+X", \
command=lambda: \
self.editor.event_generate('<<Cut>>'))
editmenu.add_command(label="Copy", \
accelerator="Ctrl+C", \
command=lambda: \
self.editor.event_generate('<<Copy>>'))
editmenu.add_command(label="Paste", \
accelerator="Ctrl+V", \
command=lambda: \
self.editor.event_generate('<<Paste>>'))
menubar.add_cascade(label="Edit", menu=editmenu)
来源:https://stackoverflow.com/questions/8449053/how-to-make-menubar-cut-copy-paste-with-python-tkinter