如何使用Python/Tkinter制作菜单栏的剪切/复制/粘贴功能

10

我想制作菜单项(在菜单栏中,而不是在右键弹出窗口中),可以剪切/复制/粘贴所选文本。

等价的键盘命令已经可以使用,而我没有做任何事情来启用它们。例如,我可以在输入框中输入文本,使用Control-X将其剪切,然后使用Control-C将其粘贴回来(或粘贴到其他位置)。

我看到的关于此主题的帖子都 boil down to cut/copy/paste for individual widgets,但这已经可以工作了。我如何使菜单项激活它们?

谢谢。

编辑: 只是为了清楚,问题是:

  • 如何使剪切/复制菜单项对任何小部件中选择的文本起作用
  • 如何使粘贴菜单项在文本光标所在的位置粘贴文本

同样,执行此操作的键盘命令( Control-x,Control-c,Control-v)已经可以使用,而无需我进行任何操作。 我知道如何制作菜单;问题只是我应该附加到菜单项的命令以产生所需的效果。

第二次编辑: 好的,我找到了一种可行的方法。因为键盘命令已经在工作,所以我们可以直接生成它们。在我的情况下,所有东西都是一个名为noteBook 的笔记本电脑,所以

lambda: self.noteBook.event_generate('<Control-x>')

可以剪切所需内容。例如:

editmenu.add_command(label="Cut", accelerator="Ctrl+X", command=lambda: self.noteBook.event_generate('<Control-x>'))

使用中:https://github.com/lnmaurer/qubit-control-interface/commit/c08c10a7fbc4a637c1e08358fb9a8593dfdf116e

但是,也可能有更好的方法来解决这个问题;如果您知道,请回复。


John,正如文本所述,所有这些代码只是为了演示目的而将内容打印到标准输出。它并没有回答我的问题。 - lnmaurer
在哪里?我使用左侧的小输入区域搜索单词'paste',发现它出现了4次。但是这些都没有回答我的问题。同样的情况也出现在'cut'上。如果你能指出页面的话,我愿意相信我要找的信息在那里;但是它肯定不在你提供链接的那一页上。 - lnmaurer
http://www.pygtk.org/docs/pygtk/class-gtkclipboard.html pyGTK有一个剪贴板功能,值得研究一下。 - John Riselvato
@JohnRiselvato:pyGTK中的函数如何帮助使用Tkinter的人?或者您是建议他们在另一个工具包中重新编写整个应用程序? - Bryan Oakley
4个回答

14
尝试这个:源代码
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()

1
谢谢,@JohnRiselvato - 很棒的例子(在这里使用了它:http://sdaaubckp.svn.sourceforge.net/viewvc/sdaaubckp/xtra/youtube-dl-gui-tkdnd/youtube-dl-gui-tkdnd.py?view=markup);干杯! - sdaau

8

使用focus_get()方法获取当前具有键盘焦点的小部件,然后将事件发送到该小部件。例如:

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

这与我在编辑2中发布的代码有实质性的不同吗? - lnmaurer
你在第二个编辑中的代码生成了一个控制字符X事件。你询问是否有更简洁的方法。这段代码生成了一个“剪切”事件并将其发送到拥有键盘焦点的小部件。因此,在我看来,它是有意义的不同和更清晰的。 - Jeff Laughlin

3

玩得开心

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

看起来你正在将键盘快捷键绑定到小部件的操作上。正如我所说,这已经可以在没有我的任何操作的情况下工作了。问题是如何使剪切/复制的菜单项对任何小部件中选择的文本起作用,并且如何使粘贴菜单项在文本光标所在的位置粘贴文本。 - lnmaurer
@BryanOakley - 是的,他应该因此受到惩罚(反话结束) - Qohelet

0

我刚看到你的问题,可惜已经晚了九个月(这算是一个怀孕的停顿吗?)。这段代码对我有效:

    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)

3
这并未回答所问的问题,该问题谈论使任何小部件都能使用剪切/复制/粘贴。你所做的只是将剪切/复制/粘贴操作绑定到单个小部件。 - Bryan Oakley

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接