我正在开发一个选举计算器(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()
不知道有没有更好的方法。我对此也很陌生。