如何在 GTK 中动态更改 SVG 图像中元素的颜色?

Leo*_*erd 3 gtk svg

以下两行代码从 SVG 文件加载图像并将其设置为窗口的图标:

GdkPixbuf *icon = gdk_pixbuf_new_from_file("icon.svg", NULL);
gtk_window_set_icon(GTK_WINDOW(win), icon);
Run Code Online (Sandbox Code Playgroud)

该 SVG 文件除其他外还包含一个定义如下的矩形:

<rect
   style="fill:#000000"
   id="screen"
   ... />
Run Code Online (Sandbox Code Playgroud)

我想rect在加载文件之后、将其设置为窗口图标之前动态更改该元素的颜色。

如果我在启动程序之前手动更改磁盘上文件的此元素的样式属性,它将达到预期的效果。但我想让程序本身设置它,以匹配它选择的颜色。

(这样我就可以在窗口切换器菜单中以及其他地方区分多个相似的窗口)

Leo*_*erd 5

我现在已经从 IRC(irc.gnome.org 上的 #gtk+)找到了这个问题的答案,并阅读了 GTK 自己的源代码。

答案涉及构建一个字符串来设置样式表并使用 XML 的 xinclude 来提取原始图像。

GdkPixbuf *load_icon(char *background)
{
  /* This technique stolen from 
   *   http://git.gnome.org/browse/gtk+/tree/gtk/gtkicontheme.c#n3180
   */

  gchar *str = g_strconcat(
      "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
      "<svg version=\"1.1\"\n"
      "     xmlns=\"http://www.w3.org/2000/svg\"\n"
      "     xmlns:xi=\"http://www.w3.org/2001/XInclude\"\n"
      "     width=\"64\"\n"
      "     height=\"64\">\n"
      "  <style type=\"text/css\">\n"
      "    #screen {\n"
      "      fill: ", background, " !important;\n"
      "    }\n"
      "  </style>\n"
      "  <xi:include href=\"" PANGOTERM_SHAREDIR "/pangoterm.svg" "\"/>\n"
      "</svg>",
    NULL);

  GInputStream *stream = g_memory_input_stream_new_from_data(str, -1, g_free);

  GdkPixbuf *ret = gdk_pixbuf_new_from_stream(stream, NULL, NULL);

  g_object_unref(stream);

  return ret;
}
Run Code Online (Sandbox Code Playgroud)