Чтобы перехватить событие вставки, необходимо сначала создать собственный класс записи (PastableEntry
в этом примере), который наследуется от gtksheet.ItemEntry
. Во время его инициализации мы подключаемся к сигналу paste-clipboard
, чтобы перехватить события вставки:
class PastableEntry(gtksheet.ItemEntry):
def __init__(self):
gtksheet.ItemEntry.__init__(self)
self.connect('paste-clipboard', self.__on_paste)
Тяжелая работа в обработчике событий. Сначала нам нужно получить содержимое буфера обмена. В Unix источники буфера обмена могут рекламировать несколько форматов данных. Исходя из вашего скриншота, я предполагаю, что вы пытаетесь скопировать данные из Gnumeric. Gnumeric поддерживает application/x-gnumeric
, text/html
, UTF8_STRING
, COMPOUND_TEXT
и STRING
. Для этого примера мы будем использовать формат UTF8_STRING, который выглядит следующим образом:
1,1 <tab> 1,2 <tab> 1,3 <newline>
2,1 <tab> 2,2 <tab> 2,3 <newline>
3,1 <tab> 3,2 <tab> 3,3
Очевидно, что это ужасно не получается, если какая-либо из ячеек содержит символ табуляции или символа новой строки, но мы будем использовать это для простоты. В реальном приложении вы можете проанализировать данные в формате application/x-gnumeric
или text/html
.
Возвращаясь к нашему классу PastableEntry, теперь мы определяем обработчик события вставки:
def __on_paste(self, entry):
clip = gtk.Clipboard()
data = clip.wait_for_contents('UTF8_STRING')
text = data.get_text()
sheet = self.parent
o_row, o_col = sheet.get_active_cell()
for i_row, row in enumerate(text.split('\n')):
for i_col, cell in enumerate(row.split('\t')):
sheet.set_cell_text(o_row + i_row, o_col + i_col, cell)
self.stop_emission('paste-clipboard')
Это должно быть совершенно очевидно. Мы разбиваем данные буфера обмена на строки (по символам новой строки), а затем на ячейки (по символам табуляции) и соответствующим образом устанавливаем значения ячеек листа.
stop_emission
существует, чтобы остановить GTK + от запуска обработчика по умолчанию для операций вставки. Без этой строки выбранная ячейка будет перезаписана необработанными данными.
Затем мы регистрируем класс с помощью GObject:
gobject.type_register(PastableEntry)
Наконец, чтобы фактически использовать наш пользовательский класс записи, передайте его конструктору gtksheet.Sheet
:
s = gtksheet.Sheet(20, 20, "Sheet 1", entry_type=PastableEntry)