2013-02-11 53 views
0

我正在使用一個GtkTreeView控件,我想更改打開和關閉子行的「擴展器」圖標的外觀:我希望圖標成爲我們所有的三元組熟悉,但它們以盒裝「+」和「 - 」符號出現。如何手動繪製GtkTreeView擴展器

起初我以爲必須有一個樣式枚舉,我可以設置,但我找不到一個。然後,我想也許有一個我可以在我的主題的gtkrc文件中設置的樣式屬性,但我不認爲它有一個。最後,我使出試圖手動覆蓋抽籤方法,像這樣:

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擴展器圖標的外觀或者自己繪製它們?

非常感謝!

回答

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; 
} 
+0

感謝您的幫助。有趣的是,你的解決方案與我在我的問題中提出的內容幾乎完全相同,但是關於我設置draw_expander函數的時機有所不同 - 我移動了(GTK_STYLE_GET_CLASS(pTreeView-> style)) - > draw_expander = my_draw_expander打電話給我所有的小部件修改後,它的工作!再次感謝,很棒的工作。 – user2062604 2013-02-12 14:23:15

0

也許你應該嘗試切換到,吸引了擴展,你要顯示他們的方式的主題,因爲我敢肯定你的一些用戶可能會覺得有點粗魯,如果你「逼」他們批准三角形是繪製膨脹體的唯一方法,並且否認它們有任何改變這種情況的機會。

這尤其是什麼主題製作的 - 這樣每個人都可以擁有她想要的外觀。

好吧,無論如何不幸的是,實際上GTK正在從版本2轉換到版本3,所以根據您使用的版本,您將不得不覆蓋另一個信號。

在GTK 3中它應該會更容易一些,因爲您已經在「draw」信號中獲得了cairo上下文,但是在GTK 2中也可以,在這裏您必須使用「expose-event」信號。

這裏以一個例子來說明如何使用GTK版本2做的一個片段。由於我不是真正的藝術家,所以它可能看起來不太好,但我相信你會想出一個漂亮的設計。

......啊,不要忘記改變它畫depedning其狀態的方式......

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

感謝您的迴應! 不幸的是,我不明白如何連接到擴展器的繪製信號,因爲我不能從GtkTreeView部件中分離出擴展器部件。 我有一個現有的GtkTreeView小部件,我需要更改它使用的擴展器的外觀。你知道怎麼做嗎? – user2062604 2013-02-11 22:16:33

+0

我不確定這是如何在GTK 3中處理的,因爲舊的樣式系統似乎已被標記爲廢棄,但對於GTK 2,您必須選擇與視圖關聯的樣式並覆蓋draw_expander方法。 – mikyra 2013-02-12 00:35:25

+0

只要看看上面的例子,如何執行此操作 – mikyra 2013-02-12 00:49:56