如何向我的应用程序添加剪切/复制/粘贴功能?

如何向我的应用程序添加剪切/复制/粘贴功能?

我正在开发一个选举计算器(https://launchpad.net/electoralcalculator) 使用 Python 2.7、Gtk+3 和 Glade,我想在我的应用程序中添加剪切/复制/粘贴功能。

我想让用户有机会使用菜单项(编辑 > 剪切、编辑 > 复制和编辑 > 粘贴)、工具栏按钮或键盘快捷键(Ctrl + X、Ctrl + C 和 Ctrl + V)来剪切/复制/粘贴文本。

如何剪切/复制所选文本?有许多文本输入小部件,所选文本可以位于其中任何一个中。

我怎样才能知道光标在哪里,以便我可以将剪贴板的内容粘贴到那里?

我发现了以下例子:
http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html

但是,虽然此示例中只有一个文本输入小部件,但在我的应用程序中却有很多这样的小部件。
我如何知道所选文本在哪里(在哪个文本输入小部件中)以便剪切/复制它?
我如何知道粘贴功能的光标在哪里?

英语不是我的母语,请原谅我的错误。

感谢您的帮助

编辑:
我根据 Ian/Timo 的代码编写了一个带有可用剪切、复制和粘贴按钮的示例。
感谢 Timo 和 Ian B. 的帮助。我非常感激。

如果示例中有错误,请告诉我。

键盘快捷键(Ctrl+X、Ctrl+C 和 Ctrl+V)可自动运行,无需添加任何代码。

from gi.repository import Gtk, Gdk

class TwotextWindow(Gtk.Window):
    __gtype_name__ = "TwotextWindow"

    def __init__(self):
        super(TwotextWindow, self).__init__()
        self.connect('delete-event', Gtk.main_quit)

        self.vbox = Gtk.VBox(False, 8)
        for x in range(4):
            self._build_entry()

        button_cut = Gtk.Button(label='Cut')
        button_cut.connect('clicked', self.on_cut_clicked)
        self.vbox.pack_start(button_cut, False, False, 0)

        button_copy = Gtk.Button(label='Copy')
        button_copy.connect('clicked', self.on_copy_clicked)
        self.vbox.pack_start(button_copy, False, False, 0)

        button_paste = Gtk.Button(label='Paste')
        button_paste.connect('clicked', self.on_paste_clicked)
        self.vbox.pack_start(button_paste, False, False, 0)

        self.add(self.vbox)
        self.show_all()

        # Code for other initialization actions should be added here.
        self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)

    def _build_entry(self):
        entry = Gtk.Entry(text='Hello, World!')
        entry.connect('focus-in-event', self.on_entry_focus)
        self.vbox.pack_start(entry, False, False, 0)

    def on_cut_clicked(self, widget):
        # Get the bounds of the selected text
        bounds = self.focus.get_selection_bounds()

        # if the bounds of the selection are not an empty tuple,
        # put the selection in the variable chars
        # and copy it to the clipboard
        # (get_selection_bounds returns an empty tuple if there is no selection)
        # then delete the selection
        if bounds:
            chars = self.focus.get_chars(*bounds)
            print "Copying '%s' from: %s" % (chars, self.focus)
            self.clipboard.set_text(chars, -1)
            print "Deleting text selection: characters from position %s to %s" % (bounds[0], bounds[1])
            self.focus.delete_text(bounds[0], bounds[1])
        else:
            print "Can't cut if you don't select text"

    def on_copy_clicked(self, widget):
        # Get the bounds of the selected text
        bounds = self.focus.get_selection_bounds()

        # if the bounds of the selection are not an empty tuple,
        # put the selection in the variable chars
        # and copy it to the clipboard
        # (get_selection_bounds returns an empty tuple if there is no selection)
        if bounds:
            chars = self.focus.get_chars(*bounds)
            print "Copying '%s' from: %s" % (chars, self.focus)
            self.clipboard.set_text(chars, -1)
        else:
            print "Can't copy if you don't select text"

    def on_paste_clicked(self, widget):
        # Get the text from the clipboard
        text = self.clipboard.wait_for_text()

        if text != None:
            # If there's text selected in the target
            # delete it and paste the contents of the clipboard
            bounds = self.focus.get_selection_bounds()
            if bounds:
                print "Deleting text selection: characters from position %s to %s" % (bounds[0], bounds[1])
                self.focus.delete_text(bounds[0], bounds[1])
                print "Pasting '%s' into: '%s' at the position %s" % (text, self.focus, bounds[0])
                self.focus.insert_text(text, bounds[0])

            # else insert the text in the current position of the cursor in the target
            else:
                pos = self.focus.get_position()
                #print "Cursor position in the target: %s" % pos
                print "Pasting '%s' into: '%s' at the position %s" % (text, self.focus, pos)
                self.focus.insert_text(text, pos)
        else:
            print "No text on the clipboard."

    def on_entry_focus(self, widget, event):
        print "Focused:", widget
        self.focus = widget


if __name__ == '__main__':
    win = TwotextWindow()
    Gtk.main()

答案1

如何使用内部变量来存储最后一个活动的小部件?使用条目的焦点事件信号(当键盘获得焦点时)用其名称修改该变量(可以对所有文本条目使用通用回调)。然后,当您需要复制或粘贴某些内容时,您可以使用该变量来知道将其放在哪里(通过 getattr)。这是我编写的一个小例子。

原始代码经过编辑,可以独立运行并解决问题

from gi.repository import Gtk, Gdk

class TwotextWindow(Gtk.Window):
    __gtype_name__ = "TwotextWindow"

    def __init__(self):
        super(TwotextWindow, self).__init__()
        self.connect('delete-event', Gtk.main_quit)

        self.vbox = Gtk.VBox(False, 8)
        for x in range(4):
            self._build_entry()

        button = Gtk.Button(label='Copy')
        button.connect('clicked', self.on_copy_clicked)
        self.vbox.pack_start(button, False, False, 0)

        self.add(self.vbox)
        self.show_all()

        # Code for other initialization actions should be added here.
        self.clipboard = Gtk.Clipboard.get(Gdk.SELECTION_CLIPBOARD)

    def _build_entry(self):
        entry = Gtk.Entry(text='Hello, World!')
        entry.connect('focus-in-event', self.on_entry_focus)
        self.vbox.pack_start(entry, False, False, 0)

    def on_copy_clicked(self, widget):
        bounds = self.focus.get_selection_bounds()
        chars = self.focus.get_chars(*bounds)
        print "Copying '%s' from: %s" % (chars, self.focus)
        #TODO: do the actual copying

    def on_entry_focus(self, widget, event):
        print "Focused:", widget
        self.focus = widget


if __name__ == '__main__':
    win = TwotextWindow()
    Gtk.main()

不知道有没有更好的方法。我对此也很陌生。

相关内容