如何手动绘制GtkTreeView扩展器

时间:2013-02-11 20:20:50

标签: gtk gtktreeview

我正在使用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扩展器图标的外观或者只是自己绘制它们?

提前感谢一大堆!

2 个答案:

答案 0 :(得分:0)

这里是如何覆盖绘图扩展器的示例代码。你肯定要看一下手册来正确获取所有参数。

#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;
}

答案 1 :(得分:0)

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

这尤其是主题的制作方式 - 这样每个人都可以拥有自己想要的外观。

嗯,不幸的是,实际上GTK正处于从版本2到版本3的转换中,因此根据您使用的版本,您将不得不覆盖另一个信号。

在GTK 3中应该有点容易,因为你已经在“绘制”信号中获得了你的cairo上下文,但是在GTK 2中也是如此,你必须使用“expose-event”信号。 / p>

这里举一个例子来说明如何使用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;
}