Я разрабатываю Избирательный Калькулятор (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()
Как насчет использования внутренней переменной для хранения последнего активного виджета? Используйте сигнал ввода в фокусе события (когда клавиатура фокусируется), чтобы изменить эту переменную с ее именем (можно использовать общий обратный вызов для всех текстовых записей). Затем, когда вам нужно что-то скопировать или вставить, вы можете использовать эту переменную, чтобы узнать, куда ее поместить (через 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()
Не знаю, есть ли лучший способ сделать это. Я тоже новичок в этом.