简体   繁体   English

如何使用Python / Tkinter进行菜单栏切割/复制/粘贴

[英]How to make menubar cut/copy/paste with Python/Tkinter

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. 例如,我可以在输入框中输入文本,使用Control-X将其剪切,然后使用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. 同样,执行此操作的关键命令(Control-x,Control-c,Control-v)已经可以在我没有做任何事情的情况下工作。 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. 编辑2:好的,我有办法。 Since the key commands already work, we can just generate them. 由于关键命令已经起作用,我们可以生成它们。 In my case, everything is aa notebook named noteBook so 在我的情况下,一切都是一个名为noteBook的笔记本

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 使用中: https//github.com/lnmaurer/qubit-control-interface/commit/c08c10a7fbc4a637c1e08358fb9a859​​3dfdf116e

Still, there's probably a cleaner way to do this; 不过,可能还有一种更清洁的方法可以做到这一点; please reply if you know it. 如果你知道的话请回复。

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()

Use the focus_get() method to get the widget which currently has keyboard focus, and then send the event to that widget. 使用focus_get()方法获取当前具有键盘焦点的窗口小部件,然后将事件发送到该窗口小部件。 Eg 例如

editmenu = Menu(menubar, tearoff=0)
editmenu.add_command(label="Cut", \
                     accelerator="Ctrl+X", \
                     command=lambda: \
                             mywindow.focus_get().event_generate('<<Cut>>'))

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()

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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM