【问题标题】:GtkSourceGutter - How to render icon or text on a specific lineGtkSourceGutter - 如何在特定行上呈现图标或文本
【发布时间】:2018-05-18 21:48:18
【问题描述】:

我已插入自定义 gtk 源 gutter 渲染器 pixbuf,我想在特定行上渲染图标。

参考 API 声明该接口与 GtkTreeView 上的接口非常相似,但不适用于树模型。 那么...如果 GtkSourceGutter 不适用于树模型,我应该如何将数据渲染到特定行?

我检查了整个库中的每个函数,每个建议的 api 和子对象,甚至没有任何提示。

这只是没有意义。手册页说 GtkSourceGutterRendererPixbuf 用于在 CELL 中显示图标。 执行gtk_source_gutter_renderer_pixbuf_set_pixbuf(renderer, pixbuf); 将呈现排水沟中所有单元格的图标。 如果唯一的方法是使用 cairo 手动绘制 pixbuf..这些渲染器有什么意义?

如何使用 gtksourcegutterrenderer在特定行中渲染 pixbuf


【问题讨论】:

  • 为什么没人接听?甚至没有关于为什么没有人回答的问题。这些东西真的是绝密吗?
  • 因为 SO 的 gtk 部分不是很好。
  • @AlexanderDmitriev 太可悲了。与 gtk 部分相比,QT 的人数相当多。而对于 C 语言的 GUI 开发,还有什么替代方案。我相信 GTK+ 可能是同类产品中最好的。

标签: c windows gtk gtksourceview gutter


【解决方案1】:

我没有使用过GtkSourceView,但我可以给你一些线索。


GtkSourceView 的作者是怎么做的

首先,我们需要一些链接:

让我们从 GtkSourceGutterRendererPixbuf 开始。从它的class_init 方法我们发现,它只覆盖draw 方法。它的唯一目的是呈现一个 pixbuf 或图标。纯绘图。

但是,GtkSourceGutterRenderer 文档说,有一个query-data 信号可用于调整 Renderer 的内部状态。此时我们应该看一下继承自 RendererPixbuf 的 GtkSourceGutterRendererMarks。它不会覆盖draw,而是覆盖query_data(由于某种原因,文档中没有描述GtkSourceGutterRendererClass。我不知道为什么。)

/* Read my comments. */
static void
gutter_renderer_query_data (GtkSourceGutterRenderer      *renderer,
                            GtkTextIter                  *start,
                            GtkTextIter                  *end,
                            GtkSourceGutterRendererState  state)
{
  GSList *marks;
  GdkPixbuf *pixbuf = NULL;
  
  view = GTK_SOURCE_VIEW (gtk_source_gutter_renderer_get_view (renderer));
  buffer = GTK_SOURCE_BUFFER (gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)));

  marks = gtk_source_buffer_get_source_marks_at_iter (buffer,
                                                      start,
                                                      NULL);
  
  /* If there are marks, we find a pixbuf for one of them. 
   * Otherwise pixbuf is NULL. */
  if (marks != NULL)
  {
    size = measure_line_height (view);
    pixbuf = composite_marks (view, marks, size);

    g_slist_free (marks);
  }
  
  /* Now tell parent class to render certain pixbuf
   * It will render nothing if pixbuf is NULL. */
  g_object_set (G_OBJECT (renderer),
                   "pixbuf", pixbuf,
                   NULL);
}

我的建议。

您想在某些行上绘制标记(例如,想突出显示当前调试器行)。如果我是你,我会从 RendererPixbuf 继承,覆盖 query_data 并在 GtkTextIter *start 上使用 gtk_text_iter_get_line。看起来这是最低限度的要求。

如有任何其他问题,请随时提出。

【讨论】:

  • 我可以在文本视图上进行纯绘图,但这将是很多工作(处理 vscroll、跟踪所有“标记”位置并分别重绘它们等)我已经完成了这之前,但是这一次,在重复相同的混淆之前(那不是 GTK+ 的味道)我决定问,因为这似乎是必须得到支持的东西。不幸的是,我没有足够的覆盖/继承实践。到目前为止,我已经实现了两个小部件,其余的是普通的 GTK+、函数和 hacks。
  • 从 GObject 子类化并不是一件难事。官方howto可以找到here
  • 为了让事情变得更容易,您可以使用 gtksourcegutterrenderermarks 标头和源代码并对其进行调整。在 .h 中,您将 GTK_SOURCEGtkSourcegtk_source 更改为您的前缀(例如,MLNMlnmln 负责任地); GUTTER_RENDERER_MARKSGutterRendererMarksgutter_renderer_marks 到您的班级名称(例如,GUTTER_RENDERER_DEBUGGERGutterRendererDebuggergutter_renderer_debugger)。不要触摸包含parent 的行。然后在.c文件中做相应的修改。
  • 如果 gtksourcemarks 使用 gtksourcegutterrenderermarks 那么我不能只更改源文件。正如您在屏幕截图中看到的,我也在使用源标记
  • 你应该复制一份然后修改。
【解决方案2】:

我个人不能简单地同意创建自定义对象很容易的说法。这并不容易,对每个人来说都不是。

主要是因为这个问题被标记为c,不了解面向对象编程的人可能不熟悉它的概念。

这是一个阅读和练习的问题。

因此,如果您不知道如何创建自己的小部件,请不要惊慌。

我能想到的最简单的解决方案,不涉及创建自己的渲染器,而是告诉渲染器如何查询渲染数据。

只需将 GtkSourceGutterRenderer 上的 query-data 信号连接到如下所示的信号处理程序:

G_MODULE_EXPORT void gutter_renderer_query_data (GtkSourceGutterRenderer *renderer, GtkTextIter *start, GtkTextIter *end, GtkSourceGutterRendererState state)
{
    GtkSourceView*      view    = NULL;
    GtkSourceBuffer*    buffer  = NULL;
    GSList*             marks   = NULL;
    GdkPixbuf*          pixbuf  = NULL;

    view    = GTK_SOURCE_VIEW(gtk_source_gutter_renderer_get_view(renderer));
    buffer  = GTK_SOURCE_BUFFER(gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)));

    marks   = gtk_source_buffer_get_source_marks_at_iter(buffer, start, NULL);

    if(marks != NULL)
    {
        char *category = gtk_source_mark_get_category(marks->data);

        if(!g_strcmp0(category, "CERTAIN_CATEGORY")) /* See note 1) */
            pixbuf = gtk_image_get_pixbuf(gtk_image_new_from_file("icon_file_here")); /* See note 2) */

        g_slist_free(marks);
    }

    g_object_set(G_OBJECT(renderer), "pixbuf", pixbuf, "yalign", 0.5, NULL);
}

注意事项

  1. GtkSourceMark 共享 GtkSourceGutterRenderer 接口,因此您可能希望通过指定应用于特定行的源标记的类别来过滤其他源标记。否则,您的自定义渲染器 pixbuf 也将被渲染到您的其他源标记。

  2. 您应该指定要在内部渲染的确切 pixbuf。这样做,您不必致电 gtk_source_gutter_renderer_pixbuf_set_pixbuf() 。您让 API 进行资源处理。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-11-06
    • 1970-01-01
    • 1970-01-01
    • 2018-01-01
    • 1970-01-01
    • 2012-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多