我在PyGTK中使用了一个GtkSheet
小部件来为我的应用程序的电子表格提供支持,它为我提供了一个API,用于从单元格中提取和推送数据. (我看过使用GtkTreeView,但似乎工作太多了)
我不明白的是如何拦截粘贴请求(通过即CTRL V),以便我可以处理它们而不是将其传递给窗口小部件.目前,从电子表格粘贴时,数据显示如下:
Source http://img503.imageshack.us/img503/8265/sourcespread.png变为Destination http://img80.imageshack.us/img80/7563/destspread.png
我应该拦截一个信号吗?
我在Ubuntu 9.10,Python 2.6上.
解决方法:
要捕获粘贴事件,您需要首先创建一个继承自gtksheet.ItemEntry的自定义条目类(在此示例中为PastableEntry).在初始化过程中,我们连接到粘贴剪贴板信号以捕获粘贴事件:
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')
它应该是不言自明的.我们将剪贴板数据拆分为行(按换行符),然后拆分为单元格(按制表符),并相应地设置Sheet单元格值.
stop_emission用于阻止GTK运行粘贴操作的默认处理程序.如果没有该行,则所选单元格将被原始数据覆盖.
然后我们用GObject注册该类:
gobject.type_register(PastableEntry)
最后,要实际使用我们的自定义条目类,请将其传递给gtksheet.Sheet的构造函数:
s = gtksheet.Sheet(20, 20, "Sheet 1", entry_type=PastableEntry)