Как я могу добавить функциональность сокращения/копии/вставки к своему приложению?

Я разрабатываю Избирательный Калькулятор (https://launchpad.net/electoralcalculator) использование Python 2.7, Gtk+3 и Поляны, и я хочу добавить функциональность сокращения/копии/вставки к своему приложению.

Я хочу дать пользователю возможность сокращать/копировать/вставлять текст с помощью пунктов меню (Редактирование> Сокращение, Редактирование> Копия и Редактирование> Вставка), кнопки на панели инструментов или сочетания клавиш (Ctrl+X, Ctrl+C и Ctrl+V).

Как я могу заставить выделенный текст сокращать/копировать его? Существует много виджетов ввода текста, и выделенный текст может быть в любом из них.

Как я могу знать, где курсор, таким образом, я могу вставить содержание буфера обмена там?

Я нашел об этом примере:
http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html

Но в то время как в этом примере существует только один виджет ввода текста, в моем приложении существуют многие из них.
Как я могу знать, где выделенный текст (в который виджет ввода текста) для сокращения/копирования его?
Как я могу знать, где курсор для функциональности вставки?

Английский язык не является моим первым языком, простите мои ошибки.

Спасибо за помощь

Править:
Я записал пример с рабочим сокращением, копией и кнопками вставки на основе кода Ian's/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()
3
задан 29 July 2012 в 06:04

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

Не знаю, есть ли лучший способ сделать это. Я тоже новичок в этом.

0
ответ дан 29 July 2012 в 06:04

Другие вопросы по тегам:

Похожие вопросы: