如何手动绘制GtkTreeView扩展器
我使用的是如何手动绘制GtkTreeView扩展器,gtk,gtktreeview,Gtk,Gtktreeview,我使用的是GtkTreeView小部件,我想更改打开和关闭子行的“扩展器”图标的外观:我希望图标是我们都熟悉的三角形,但它们显示为方框中的“+”和“-”符号 起初我认为必须有一个可以设置的样式枚举,但我找不到。然后,我想也许我可以在我的主题的gtkrc文件中设置一个样式属性,但我认为没有。最后,我尝试手动覆盖draw方法,如下所示: GtkWidget *pTreeView = gtk_tree_view_new_with_model((GtkTreeModel *)pTreeModel); (
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\u expander\u override()
从未被调用,而且扩展器仍然是方框中的“+”和“-”图标
有人知道如何更改GtkTreeView
扩展器图标的外观,或者自己绘制它们吗
提前多谢 这里是如何覆盖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;
}
#包括
#包括
枚举{
上校1,
努科尔斯
};
空心拉伸扩展器(GtkStyle*样式,
GdkWindow*窗口,
GtkStateType状态_类型,
GdkRectangle*区域,
GtkWidget*小部件,
const gchar*详细信息,
金特x,
金蒂,
GtkExpanderStyle扩展器(U型){
开罗*cr;
cr=gdk_cairo_create(窗口);
cairo\u set\u source\u rgb(cr,0,0,0);
开罗移动到(cr,0,0);
开罗线(cr,0,10);
开罗线(cr,10,5);
开罗路(cr);
脑卒中(cr);
}
GtkWidget*构建视图();/*你自己供应就行了*/
int main(int argc,char*argv[]){
gtk_init(&argc,&argv);
GtkWidget*窗口;
GtkWidget*视图;
window=g_object_new(GTK_TYPE_window,NULL);
视图=构建视图();
gtk_容器添加(gtk_容器(窗口),视图);
GtkStyle*style=gtk_小部件_获取_样式(视图);
GtkStyleClass*klass=GTK_STYLE_GET_CLASS(STYLE);
klass->draw\u expander=draw\u expander;
gtk_小部件_全部显示(窗口);
gtk_main();
返回0;
}
也许你应该试着切换到一个主题,以你想要的方式绘制扩展器,因为我很确定,如果你“强迫”你的一些用户认可三角形是绘制扩展器的唯一方式,并且拒绝他们改变这一点,他们可能会觉得有点粗鲁
这就是主题设计的目的——这样每个人都可以拥有她想要的外观
嗯,无论如何,不幸的是,实际上GTK正在从版本2过渡到版本3,因此根据您使用的版本,您必须覆盖另一个信号
在GTK3中应该更容易一点,因为您已经在“draw”信号中获得了开罗上下文,但是在GTK2中也可以,这里您必须使用“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;
}
#包括
#包括
gboolean绘图(GtkWidget*小部件、GdkEventExpose*事件、gpointer数据){
开罗*cr;
cr=gdk\u cairo\u create(小部件->窗口);
cairo\u set\u source\u rgb(cr,0,0,0);
开罗移动到(cr,0,0);
开罗线(cr,0,10);
开罗线(cr,10,5);
开罗路(cr);
脑卒中(cr);
返回TRUE;
}
int main(int argc,char*argv[]){
gtk_init(&argc,&argv);
GtkWidget*窗口;
GtkWidget*扩展器;
window=g_object_new(GTK_TYPE_window,NULL);
expander=g_object_new(GTK_TYPE_expander,NULL);
gtk_容器添加(gtk_容器(窗口)、扩展器);
g_信号_连接(扩展器,“暴露事件”,绘图,空);
gtk_小部件_全部显示(窗口);
gtk_main();
返回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;
}
#包括
#包括
gboolean绘图(GtkWidget*小部件,GdkEventExpose*事件){
开罗*cr;
cr=gdk\u cairo\u create(小部件->窗口);
cairo\u set\u source\u rgb(cr,0,0,0);
开罗移动到(cr,0,0);
开罗线(cr,0,10);
开罗线(cr,10,5);
开罗路(cr);
脑卒中(cr);
返回TRUE;
}
int main(int argc,char*argv[]){
gtk_init(&argc,&argv);
GtkWidget*窗口;
GtkWidget*扩展器;
GtkWidgetClass*klass;
window=g_object_new(GTK_TYPE_window,NULL);
expander=g_object_new(GTK_TYPE_expander,NULL);
gtk_容器添加(gtk_容器(窗口)、扩展器);
klass=g_型_类_peek(GTK_型_膨胀机);
klass->expose_event=draw;
gtk_小部件_全部显示(窗口);
gtk_main();
返回0;
}
非常感谢您的回复!不幸的是,我不知道如何连接到扩展器的绘图信号,因为我无法将扩展器小部件与GtkTreeView小部件隔离。我有一个现有的GtkTreeView小部件,我需要更改它使用的扩展器的外观。你知道怎么做吗?我不知道在GTK 3中如何处理这个问题,因为旧的样式系统似乎被标记为不推荐使用,但在GTK 2中,你必须选择与视图相关联的样式并覆盖draw_expander方法。只需看一下上面的示例如何执行此操作谢谢你的帮助。有趣的是,您的解决方案与我在问题中提出的几乎完全相同,但设置draw_expander函数的时间却完全不同——在我所有的小部件修改之后,我将(GTK_STYLE_GET_类(pTreeView->STYLE))->draw_expander=my_draw_expander调用移动到了,并且成功了!再次感谢,干得好。