I\'m using a GtkSheet widget in PyGTK to power my application\'s spreadsheet, and it gives me an API to pull and push data out of cells. (I looked at using GtkTreeView, but it s
To catch the paste event, you need to first create a custom entry class (PastableEntry
in this example) that inherits from gtksheet.ItemEntry
. During its initialisation, we connect to the paste-clipboard
signal to trap paste events:
class PastableEntry(gtksheet.ItemEntry):
def __init__(self):
gtksheet.ItemEntry.__init__(self)
self.connect('paste-clipboard', self.__on_paste)
The hard work is in the event handler. First we need to get the clipboard contents. In Unix, clipboard sources can advertise multiple data formats. Based on your screenshot, I assume you're trying to copy data from Gnumeric. Gnumeric supports application/x-gnumeric
, text/html
, UTF8_STRING
, COMPOUND_TEXT
, and STRING
. For this example we'll use the UTF8_STRING format, which looks like this:
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
Obviously this fails horribly if any of the cells contain a tab or newline character, but we'll use this for simplicity. In a real world application you may want to parse the application/x-gnumeric
or text/html
formatted data.
Back to our PastableEntry class, now we define the paste event handler:
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')
It should be quite self-explanatory. We split the clipboard data into rows (by newline characters) and then into cells (by tab characters), and set the Sheet cell values accordingly.
The stop_emission
is there to stop GTK+ from running the default handler for paste operations. Without that line, the selected cell will be overwritten with the raw data.
We then register the class with GObject:
gobject.type_register(PastableEntry)
Finally, to actually use our custom entry class, pass it to the constructor of gtksheet.Sheet
:
s = gtksheet.Sheet(20, 20, "Sheet 1", entry_type=PastableEntry)