0

我正在使用一个GtkTreeView小部件,我想更改打开和关闭子行的“扩展器”图标的外观:我希望这些图标是我们都熟悉的三角形,但它们显示为盒装“ +" 和 "-" 符号代替。

起初我认为必须有一个我可以设置的样式枚举,但我找不到。然后,我想也许我可以在我的主题的 gtkrc 文件中设置一个样式属性,但我认为没有。最后,我尝试手动覆盖 draw 方法,如下所示:

GtkWidget *pTreeView = gtk_tree_view_new_with_model((GtkTreeModel *)pTreeModel);
(GTK_STYLE_GET_CLASS(pTreeView->style))->draw_expander = my_draw_expander_override;

my_draw_expander_override()永远不会被调用,扩展器仍然是盒装的“+”和“-”图标。

有谁知道如何更改GtkTreeView扩展器图标的外观或自己绘制它们?

提前致谢!

4

2 回答 2

0

这里是如何覆盖draw_expander的示例代码。您肯定必须查看手册才能正确设置所有参数。

#include <gtk/gtk.h>
#include <cairo.h>


enum {
  COL_1,
  N_COLS
};

void draw_expander (GtkStyle        *style,
                    GdkWindow       *window,
                    GtkStateType         state_type,
                    GdkRectangle    *area,
                    GtkWidget       *widget,
                    const gchar     *detail,
                    gint         x,
                    gint         y,
                    GtkExpanderStyle     expander_style) {


  cairo_t *cr;

  cr = gdk_cairo_create (window);

  cairo_set_source_rgb(cr, 0, 0, 0);

  cairo_move_to (cr, 0, 0);
  cairo_line_to (cr, 0, 10);
  cairo_line_to (cr, 10, 5);
  cairo_close_path (cr);

  cairo_stroke  (cr);
}


GtkWidget *build_view (); /* just supply your own */


int main (int argc, char *argv[]) {
  gtk_init (&argc, &argv);

  GtkWidget *window;
  GtkWidget *view;

  window = g_object_new (GTK_TYPE_WINDOW, NULL);  
  view = build_view ();
  gtk_container_add (GTK_CONTAINER (window), view);

  GtkStyle *style = gtk_widget_get_style (view);
  GtkStyleClass *klass = GTK_STYLE_GET_CLASS (style);

  klass->draw_expander = draw_expander;

  gtk_widget_show_all (window);
  gtk_main ();

  return 0;
}
于 2013-02-11T21:16:49.600 回答
0

也许您应该尝试切换到以您希望它们显示的方式绘制扩展器的主题,因为我很确定如果您“强迫”他们批准三角形是一个,您的一些用户可能会觉得有点粗鲁并且唯一的方法是吸引扩展器并拒绝他们任何改变这一点的机会。

这尤其是主题的目的 - 这样每个人都可以拥有她想要的外观。

好吧,无论如何不幸的是实际上 GTK 正处于从版本 2 到版本 3 的过渡中,因此根据您使用的版本,您将不得不覆盖另一个信号。

在 GTK 3 中应该更容易一些,因为您已经在“draw”信号中获得了 cairo 上下文,但在 GTK 2 中也是可能的,在这里您必须使用“expose-event”信号。

这里作为示例,这里是如何使用 GTK 版本 2 进行操作的片段。由于我不是真正的艺术家,它可能看起来不太好,但我相信你会想出一个不错的设计。

......啊,别忘了根据它的状态改变它的绘制方式......

#include <gtk/gtk.h>
#include <cairo.h>


gboolean draw (GtkWidget *widget, GdkEventExpose *event, gpointer data) {

  cairo_t *cr;

  cr = gdk_cairo_create (widget->window);

  cairo_set_source_rgb(cr, 0, 0, 0);

  cairo_move_to (cr, 0, 0);
  cairo_line_to (cr, 0, 10);
  cairo_line_to (cr, 10, 5);
  cairo_close_path (cr);

  cairo_stroke  (cr);

  return TRUE;
}


int main (int argc, char *argv[]) {
  gtk_init (&argc, &argv);

  GtkWidget *window;
  GtkWidget *expander;


  window = g_object_new (GTK_TYPE_WINDOW, NULL);  
  expander = g_object_new (GTK_TYPE_EXPANDER, NULL);
  gtk_container_add (GTK_CONTAINER (window), expander);

  g_signal_connect (expander, "expose-event", draw, NULL);

  gtk_widget_show_all (window);
  gtk_main ();

  return 0;
}

编辑:

正如我所看到的,您似乎不想仅更改一个实例的外观,而是更改所有扩展器的外观。为此,您必须像这样覆盖默认处理程序:

#include <gtk/gtk.h>
#include <cairo.h>


gboolean draw (GtkWidget *widget, GdkEventExpose *event) {

  cairo_t *cr;

  cr = gdk_cairo_create (widget->window);

  cairo_set_source_rgb(cr, 0, 0, 0);

  cairo_move_to (cr, 0, 0);
  cairo_line_to (cr, 0, 10);
  cairo_line_to (cr, 10, 5);
  cairo_close_path (cr);

  cairo_stroke  (cr);

  return TRUE;
}


int main (int argc, char *argv[]) {
  gtk_init (&argc, &argv);

  GtkWidget *window;
  GtkWidget *expander;
  GtkWidgetClass *klass;

  window = g_object_new (GTK_TYPE_WINDOW, NULL);  
  expander = g_object_new (GTK_TYPE_EXPANDER, NULL);
  gtk_container_add (GTK_CONTAINER (window), expander);

  klass = g_type_class_peek (GTK_TYPE_EXPANDER);
  klass->expose_event =  draw;

  gtk_widget_show_all (window);
  gtk_main ();

  return 0;
}
于 2013-02-11T21:33:44.757 回答