使用GtkTextView显示大量生成的文本(自定义GtkTextBuffer?)

时间:2015-08-30 04:57:29

标签: python model-view-controller gtk3 gtktextview

我想编写一个使用GTK(通过gi.repository)的Python应用程序来显示大量数据的文本视图。 (具体来说,是从程序中反汇编的指令,类似于IDA所示。)

我认为这应该相当简单:使用普通的GtkTextView和GtkTextBuffer的自定义子类,它将处理“给我一些文本”请求,生成一些文本(反汇编一些指令)和一些标签(用于着色,格式化)等等)并将它们归还。

问题是我找不到任何关于如何以这种方式继承GtkTextBuffer的信息,我自己提供文本。我试过在我的子类中实现get_textget_slice方法,但它们似乎永远不会被调用。似乎我唯一能做的就是使用标准的GtkTextBuffer和set_text方法,并尝试以某种方式跟踪光标位置和要显示的行数,但这似乎与MVC应该如何工作完全相反。可能有数百万行,因此提前生成所有文本是不可行的。

我正在使用Python 3.4和GTK3。

1 个答案:

答案 0 :(得分:0)

Gtk.TextBuffer来自不是用Python编写的外部库。你遇到了这种情况的一个限制。对于大多数Python库,您可以将它们的类子类化,或者根据需要对它们的API进行monkeypatch。另一方面,GTK的C代码并不知道它是从Python中使用的,正如您所注意到的那样,完全忽略了被覆盖的get_text()get_slice()方法。

GTK的类还有一个限制,即您只能覆盖已声明为“虚拟”的方法。以下是转换为Python的方法:您可以在Python GI文档(example for Gtk.TextBuffer)中看到虚拟方法列表。这些方法都以do_开头,并不打算从您的程序中调用,只是被覆盖。 Python GI将使GTK代码知道这些覆盖,因此当您覆盖(例如do_insert_text()并随后调用insert_text()时),调用链将如下所示:

  • Python insert_text()
    • C gtk_text_buffer_insert_text()
      • C GtkTextBufferClass->insert_text()(内部虚方法)
        • Python do_insert_text()

不幸的是,正如您从上面链接的文档中看到的那样,get_text()get_slice()不是虚拟的,因此您无法在子类中覆盖它们。

您可以通过将一个TextBuffer(其中包含完整的反汇编指令)包装在另一个中来实现您的目标(其中包含摘录,并且实际上已连接到文本视图。)您可以在第一个文本缓冲区中设置标记以显示摘录应该从哪里开始或结束,并连接信号,以便当第一个文本缓冲区中的文本发生更改或标记发生更改时,标记之间的文本将复制到第二个文本缓冲区