通过 GTK 中的剪贴板处理电子表格数据

发布于 2024-08-17 06:42:50 字数 608 浏览 6 评论 0原文

我在 PyGTK 中使用 GtkSheet 小部件来为我的应用程序的电子表格提供支持,它为我提供了一个 API,可以从单元格中提取和推送数据。 (我查看了使用 GtkTreeView,但似乎工作量太大)

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

来源变为 Destination

有我应该拦截的信号吗?

我使用的是 Ubuntu 9.10,Python 2.6。

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
becomes Destination

Is there a signal I should intercept?

I'm on Ubuntu 9.10, Python 2.6.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

_失温 2024-08-24 06:42:50

要捕获粘贴事件,您需要首先创建一个继承自 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-gnumerictext/htmlUTF8_STRINGCOMPOUND_TEXTSTRING< /代码>。对于本例,我们将使用 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-gnumerictext/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)

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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文