原文地址:
http://hi.baidu.com/lammy/blog/item/8adf8ad6a8bbc72606088b46.html#lastcmt
GTK的RC----让动态的换皮肤立竿见影【原】
2009年07月15日 星期三 21:00
《Apress.Foundations.of.GTK.plus.Development》作为一本入门级的书很好,但是要深入,这本书就有点力不从心了。最近在学习RC文件的编写时,我脑子里有这么一个概念:从GTK的设计上来看,它应该支持GTK程序换皮肤,那么在目前带有显示屏的电子设备中,它的前途真不能小看,特别是正在发展中的STB。
学习完书中关于RC的内容后,感觉很简单,就一个gtk_rc_parse()函数就能搞定它,哪想我在实际实践中却是一波三折,从上周5开始,一有空便研究这个功能,始终抱着一个信念:既然GTK采用RC文档来管理它的style。那么这么强大的GTK不会连换皮肤都不能实现。一开始我是这么做的: Fun1() { ... gchar *pRcFilePath; pRcFilePath = RC文件//动态获取其中一个RC文件中 gtk_rc_parse(pRcFilePath ); ... } 以上只有当触发某个事件时才执行。当时我很激动的去触发那个事件,希望能看到我想要的结果,可是无论我怎么弄它都不动。一下找不到北,只有求助于GG,不知是国人太过于保守还是国人不屑这个问题,网上有人也碰到此问题,可是给出的回复没几个,且多半都是废话。后来求救于QQ群,也希望能给出点思路,因为我认为这个换皮肤这个功能在项目中肯定要用到的,在群里,有人很热心的跟我讨论了下,但还是没有得到解决。看来在国内还真是这句话中:求人不如求己。 从上周5到今天,我白天在公司由于事情不是太多,我一有时间便去研究源码,可那个源码啊,我的个乖乖哟,好几十M呢!不好啃,但自生下来就没有服输过的我,决定啃。开始的几天我拿着那个源码东看看西看看,实在看不清楚个思路,但还是坚持了下来。现在回想起来开始那几天真的很有意义,尽管没有看懂,但是很多不明白的词已经印在我脑海里,为我今天质的变化提供了必要条件,今天真是一个五味瓶的日子,终于通过源码解决此问题;但今天也挨了老大一顿批,哎,认了。 先贴上可以实现换皮肤的源码: Fun2() { ... gchar *pRcFilePath; GtkSettings *pRootSettings; pRcFilePath = RC文件//动态获取其中一个RC文件中 gtk_rc_parse(pRcFilePath ); gtk_rc_reparse_all(); pRootSettings = gtk_settings_get_default(); gtk_rc_reset_styles(pRootSettings); ... } 好,闲话不说了,先说说我比较简单理解吧,首先我们要知道函数gtk_rc_parse()到底干了啥,一下是它的函数内容: void gtk_rc_parse (const gchar *filename) { GSList *tmp_list; g_return_if_fail (filename != NULL);//判断filename 是否存在 add_to_rc_file_list (&global_rc_files, filename, TRUE);//因为GTK是支持多个RC文件的,也就是支持换皮肤,所以它内核里面是通过链表来管理RC文件的。自然要先把RC文件添加到链表中。但不解析 for (tmp_list = rc_contexts; tmp_list; tmp_list = tmp_list->next) gtk_rc_context_parse_file (tmp_list->data, filename, GTK_PATH_PRIO_RC, TRUE);//上一个函数把RC文件添加到链表中时,它是还没有解析,这就是模块化的好处,这个函数就是解析filename,并把链表的一个reload置为TRUE,表示需要重新加载。 } 从上面的注释可以明白该函数只是添加RC并解析RC文件,但是没有加载在应用软件中去,所以我刚开始写的 Fun1()自然就不能实现。 函数gtk_rc_reparse_all从函数名可以明白它是用来重新解析所有RC文件的。但是它只能加载在你创建新的对话框或控件中,而原窗体却纹丝不动。那么怎么要让原窗体也发生变化呢,而此时为什么不变化呢,我是这么理解的,因为每一个控件都有一块内存池管理它,但是它的属性应该在内存池里面。尽管你加载了RC,但是这块内存池里面的RC属性却还是原来的属性。 函数gtk_rc_reset_styles从GTK对它注释如下: /** * gtk_rc_reset_styles: * @settings: a #GtkSettings * * This function recomputes the styles for all widgets that use a * particular #GtkSettings object. (There is one #GtkSettings object * per #GdkScreen, see gtk_settings_get_for_screen()); It is useful * when some global parameter has changed that affects the appearance * of all widgets, because when a widget gets a new style, it will * both redraw and recompute any cached information about its * appearance. As an example, it is used when the default font size * set by the operating system changes. Note that this function * doesn't affect widgets that have a style set explicitely on them * with gtk_widget_set_style(). * * Since: 2.4 **/ 这个函数是对所有空间的styles重新设置并重绘。 哈哈,终于解决换皮肤功能,好开心哦,哦耶! |