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

Using GtkTextView to display lots of generated text (custom GtkTextBuffer?)

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

我认为这应该相当简单:使用普通的 GtkTextView 和 GtkTextBuffer 的自定义子类来处理 "give me some text" 请求,生成一些文本(反汇编一些指令)和一些标签(用于着色,格式化等)和 return 它们。

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

我正在使用 Python 3.4 和 GTK3。

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

GTK 的 类 还有一个限制,即您只能覆盖已声明的方法 "virtual"。下面是如何转换为 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(包含您的全部反汇编指令)包装在另一个(包含摘录,并且实际上连接到文本视图)中来实现您的目标。您可以在第一个文本缓冲区中设置标记以显示摘录的开始或结束位置,并连接信号,以便当第一个文本缓冲区中的文本发生变化或标记发生变化时,标记之间的文本将复制到第二个文本缓冲区。