在GTK中通过剪贴板处理电子表格数据 [英] Handling spreadsheet data through the clipboard in GTK

查看:138
本文介绍了在GTK中通过剪贴板处理电子表格数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 GtkSheet 小部件在PyGTK中为我的应用程序的电子表格提供动力,并且它提供了一个API来将数据从单元中拉出并推出。 (我看着使用GtkTreeView,但它似乎是太多的工作)

我不明白的是如何拦截粘贴请求(通过即CTRL + V ),以便我可以处理它们而不是将它传递给小部件。目前,从电子表格粘贴时,数据显示如下:

来源http://img503.imageshack.us/img503/8265/sourcespread.png 变成目的地http://img80.imageshack.us/img80/7563/destspread.png



是有一个信号我应该拦截?



我在Ubuntu 9.10,Python 2.6。

解决方案为了捕获粘贴事件,你需要首先创建一个自定义的入口类(在本例中为 PastableEntry ),它继承自 gtksheet.ItemEntry 。在初始化期间,我们连接到粘贴剪贴板信号以捕获粘贴事件:

  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<标签> 1,3< newline> 
2,1<标签> 2,2<标签> 2,3< newline>
3,1<标签> 3,2<标签> 3,3

显然,如果任何单元格包含制表符或换行符,则会失败,但我们为简单起见,我会使用它。在真实世界的应用程序中,您可能需要解析 application / x-gnumeric text / html 格式的数据。 / p>

回到我们的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,枚举中的行(text.split('\\\
')):
for i_col,cell in枚举(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)


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 seemed to be too much work)

What I don't understand is how to intercept paste requests (via ie. CTRL+V) so that I can process them rather than passing it through to the widget. Currently, when pasting from a spreadsheet the data shows up as follows:

Source http://img503.imageshack.us/img503/8265/sourcespread.png becomes Destination http://img80.imageshack.us/img80/7563/destspread.png

Is there a signal I should intercept?

I'm on Ubuntu 9.10, Python 2.6.

解决方案

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)

这篇关于在GTK中通过剪贴板处理电子表格数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆