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

10 投票
4 回答
20861 浏览
提问于 2025-04-17 08:03

我想在菜单栏中添加一些菜单项,可以对选中的文本进行剪切、复制和粘贴操作,而不是在右键弹出的窗口中进行。

其实,键盘的快捷键已经可以直接使用,不需要我做什么特别的设置。比如,我可以在输入框中输入文本,按下 Control-X 剪切,然后用 Control-C 粘贴回去(或者粘贴到其他地方)。

我看到的相关帖子主要讨论的是如何对单个控件进行剪切、复制和粘贴,但这些功能已经可以用了。我的问题是,如何让菜单项来激活这些功能呢?

谢谢。

编辑:

为了更清楚,我的问题是:

  • 如何让剪切和复制的菜单项作用于任何控件中选中的文本
  • 如何让粘贴菜单项在文本光标所在的位置粘贴文本

再说一次,执行这些操作的快捷键(Control-x、Control-c、Control-v)已经可以用了,我只想知道该把什么命令绑定到菜单项上,以达到想要的效果。

编辑 2:

好的,我找到了一种可行的方法。因为快捷键已经可以用了,所以我们可以直接生成这些命令。在我的例子中,所有内容都在一个叫 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

不过,可能还有更简洁的方法,如果你知道,请告诉我。

4 个回答

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

使用 focus_get() 方法可以获取当前拥有键盘焦点的控件,然后将事件发送给那个控件。例如:

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

撰写回答