Как добавить функцию вырезания / копирования / вставки в мое приложение?
Я занимаюсь разработкой Избирательного калькулятора ( https://launchpad.net/electoralcalculator) с использованием Python 2.7, Gtk+3 и Glade, и я хочу добавить функцию вырезания / копирования / вставки в свое приложение.
Я хочу дать пользователю возможность вырезать / копировать / вставлять текст с помощью пунктов меню ("Правка"> "Вырезать", "Правка"> "Копировать" и "Правка"> "Вставить"), кнопок панели инструментов или сочетаний клавиш (Ctrl+X, Ctrl+C и Ctrl +). В).
Как я могу получить выделенный текст, чтобы вырезать / скопировать его? Есть много виджетов для ввода текста, и выделенный текст может быть в любом из них.
Как я могу узнать, где находится курсор, чтобы я мог вставить туда содержимое буфера обмена?
Я нашел об этом примере:
http://python-gtk-3-tutorial.readthedocs.org/en/latest/clipboard.html
Но хотя в этом примере есть только один виджет для ввода текста, в моем приложении их много.
Как я могу узнать, где находится выделенный текст (в каком виджете ввода текста), чтобы вырезать / скопировать его?
Как я могу узнать, где находится курсор для функции вставки?
Английский не мой родной язык, пожалуйста, прости мои ошибки.
Спасибо за вашу помощь
РЕДАКТИРОВАТЬ:
Я написал пример с рабочими кнопками вырезания, копирования и вставки на основе кода Яна / Тимо.
Спасибо вам, Тимо и Яну Б., за вашу помощь. Я очень ценю это.
Дайте мне знать, если что-то не так в примере.
Сочетания клавиш (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()
Не знаю, есть ли лучший способ сделать это. Я тоже новичок в этом тоже.