转载自:
http://chujb.spaces.live.com/blog/cns!21F0BD7DB657E864!277.entry?wa=wsignin1.0&sa=55687757
在做GTK开发得时候,使用到了GTK中的RC文件。使用心得记录如下:
(1)、GTK 主题指南
1.Widgets
GTK拥有一套大量的widget集合,如按钮,滚动条,编辑框等,每一种组件的属性都可以单独进行配置。
所有的widget由GtkWidget派生出来的。也就是说,更改GtkWidget的属性所有的widgets会受到影响。幸运的是,大多数widget有其父类,如GtkButton的属性同样使GtkCheckButton生效,除非你对其进行单独的配制。
widgets, 一些常用元素:/GnomePanel /GtkButton /GtkCheckButton /GtkColorButton /GtkComboBox /GtkComboBoxEntry /GtkEntry /GtkFrame /GtkMenu /GtkMenuBar /GtkMenuItem /GtkNotebook /GtkProgressBar /GtkRadioButton /GtkScale /GtkSpinButton /GtkStatusbar /GtkTreeView /StyleProperties /SymbolicColors
2.Styles
用户自定义GtkWidget形成自己的风格,定义的方式有两种形式,一种是以使用Gtk中的style,但style定义方式中只给出了几种有限风格属 性,如设置滚动条的宽度。另一种就是通过使用engine这种机制来实现,其中定义很多的属性可供使用时选择。
通过定义不同的styles合并在一起成为一个最终的Gtk主题,所以通常可以定义出一个基本的风格,其包含一此通用的选项配置,对于定义组件专有的属性可以在引用它的基础上做设置,如颜色的修改.
3.Engines
与styles组合实现出更有吸引力的风格,gtk内部实现很多可供选择的风格。
4.gtkrc文件
一个rc文件被称为gtkrc,存放的地方取决于系统的配置,通常放在/usr/share/themes/themename目录下,存在gtk-2.0/gtkrc文件,此文件可以是一个rc文件,里面定义了gtk中各种组件的配置。
1)修改构件的属性:
fg:设置一个构件的前景色
bg:设置一个构件的背景色
text:可编辑文本构件的前景色
base:可编辑文本构件的背景色
bg_pixmap:显示像素图的构件的背景色
font_name:设置字体风格
xthickness:设置左右边界的宽度
ythickness:设置上下边界宽度
2)每一构件的分为五种状态:
NORMAL:鼠标没有覆盖,点击的状态
PRELIGHT:鼠标在组件之上
ACTIVE:鼠标被按下或点击的状态,
INSENSITIVE:不能被激活,或点击的状态
SELECTED:被选对象可以带好多属性
3)风格绑定:
1.将一种风格绑定到组件类
格式:class "GtkButton" style "my-button" 将“my-button"风格绑定到GtkButton的所有实例
widget_class "*Text*" style "bright_yellow"
将"bright_yellow"风格绑定到名字中含有“Text“的组件
2.组件嵌套的方式widget_class
如widget_class "*.GtkButton.*" style "button-content"
3.应用指定风格
如果一个应用开发者已经明确陈列一种元素,在gtkrc文件中指明元素名,来将它风格化。
eg: widget “funky bar“ style “mystyle“
4.风格绑定的优先次序
对widget的rc风格绑定 > 对widget_class风格的绑定 > class 同一种组件的多种声明是,后一种优于前一种。指定优先的highest,rc,theme,application,gtk,lowest将覆盖上述的风 格绑定,
4)组件指定风格:
gtk api文档列表中,列出的style properties,对某种widget类型,是明确的,eg。GtkWiget::focus-line-width = 2
5)高级指定风格(依据gtk2正式文档):
界定符#,注释所在行的内容,在解析gtkrc文件时,将此行被忽略掉。
1.binding name {...} 声明绑定设置
2.calss pattern [ style | binding [ : priority ]] name 对继承层的一个具体的分支,指定风格或绑定设置
3.include finename: 在此处引入文件,如果不是包含绝对路径的文件名,将会在当前打开rc文件的文件夹下,搜索此文件
4.module_path path: 设置搜索rc文件中涉及的主题引擎路径。
5.pixmap_path path: 设置搜索像素图的路径。
6.widget pattern [ style | binding [ : priority ]] name 给路径名上相配匹配的一组具体的组件设置风格或绑定。
7.widget_class pattern [ style | binding [ : priority ]] nane 给路径名上相匹配的一组具体的组件设置风格或绑定。
5.widget设置示例:
* Buttons:
buttons不存在背景的设置,只能通过对其所处的widget上添加背景的处理。
bevelling (relief): 对button进行三种状态的设置: GTK_RELIEF_NORMAL, GTK_RELIEF_HALF, GTK_RELIEF_NONE.
* Labels:
不存在背景色,估计可以通过text[]这一属性设置其前景色
* Text Boxes:
背景: base[NORMAL]
文本颜色: text[NORMAL]
应用自定义的风格: widget_class "*TextView*" style "my_style"
改变编辑时光标的颜色eg: GtkWidget::cursor-color "red"
* Scrollbars and Scales:
使用 widget_class "*Scrollbar*" 来指定scrollbars.
arrow button and main draggable rectangle colour is controlled by bg[NORMAL]
槽和边框设置背景色 bg[ACTIVE]
鼠标光标移动scrollbar(滚动条)上时的颜色使用bg[PRELIGHT]设置
光标箭头的颜色fg[NORMAL]
* Combobox: http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBox
combobox是一个按钮包含:label, separator, and arrow
* Icons:
设置自定义的图标
stock["my-stock-item"] =
{
{ "itemmenusize.png", *, *, "gtk-menu" },
{ "itemtoolbarsize.png", *, *, "gtk-large-toolbar" }
{ "itemgeneric.png" } /* implicit *, *, * as a fallback */
}
* Menus:
菜单是一个组合控件,包括menubar和menuitems.
* Lists:
与Treeview组合为一个整体.
* Treeview:
Treeview开为两部分:head_window,bin_window,该组件可以按元素列表和树的形式显示
Treeview 背景色是通过base[]控制,如果处于非关注状态则按base[ACTIVE]的着色显示.
设置Treeview的列的顶部的颜色,使用bg控制.
Treeview列的顶部为一个按钮. 指定widget_class "*TreeView.GtkButton*". 指定顶部文本的颜色The text colour in the heads is controlled with fg, and not text.
The default line spacing of TreeView lists is quite large. It is not possible to reduce it in the rc file. This is a known issue.
Treeview 风格自属性有: allow-rules, even-row-color, expander-size, horizontal-separator, indent-expanders, odd-row-color, vertical-separator.
* Tabs:
文本内容在非选中的tab上使用的是fg[ACTIVE],背景色设置bg[ACTIVE].
定义tabs文本设置 widget_class "*GtkNotebook*GtkLabel".
* engine
gtk engines 给开发者提供大量不同的显示风格选项。通过使用不同的engine来设置不同风格的组件。
style "some-style" {
engine "clearlooks" {
# engine specific settings go here
}
}
颜 色可以使用颜色的名称(GTK+ knows all names from the X color database /usr/lib/X11/rgb.txt),使用一种16进制的形式例如#rrrrggggbbbb, #rrrgggbbb, #rrggbb, or #rgb。r,g,b是16进制的整数(0-65535)或者是浮点数字0.0-1.0。
从2.10开始颜色可以使用符号颜色 以@color-name 或者是用表达式合成颜色。
(2)、如何从开始理解gtkrc在实践中的使用
GTK 有自己缺省处理应用程序的方法,这就是使用rc配置文件。这些文件可用于给几乎任何构件设置颜色,也能为一些构件的背景贴上一幅像素图。
rc 文件的功能
在你的应用程序开始处,应包含一个如下的函数调用:
void gtk_rc_parse( char *filename );
把 rc 文件名传递给被调用的函数,随后 GTK 会解析这个文件,并且使用文件中所定义构件类型的风格设置。
如果希望定义一套和其它构件集或同一构件集中其它逻辑部分具有不同风格的特定构件集,使用以下函数调用:
void gtk_widget_set_name( GtkWidget *widget, gchar *name );
把新创建的构件作为第一个参数,把你给该构件定的名程作为第二个参数。这使你能够在 rc 文件中按名称更改这个构件的属性。
如果我们使用了一个如下的函数调用:
button = gtk_button_new_with_label ("redred");
gtk_widget_set_name (button,"redred");
那么这个按钮取名为"redred",并且在 rc 文件中可能通过像"redred button.GtkButton"这样的名称找到它。
后面作为示例的 rc 文件,设置主窗口的属性,告诉所有子窗口继承在"main button"风格项中规定的风格。在应用程序中的代码为:
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name (window, "main window");
然后在 rc 文件中用如下一行定义它的风格:
widget "main window.*GtkButton*" style "main_button"
该定义把"主窗口"中的所有按钮构件设置为 rc 文件中定义的"main_buttons"风格。
如你所见,这是一个非常强大和灵活的系统。如何最大限度的利用它的优势需要使用你的想象力。)
(3)、背景介绍
什么是gtk主题引擎?
主题引擎是应用程序主题使用的一些代码。如今,已有许多不同的主题引擎存在。GTK + 主题由三件事: 一个主题引擎 ,这是一个共享对象包括代码的图形要素,一个配置文件来配置的运作主题的引擎和核心部分基于GTK +和额外的数据文件的主题引擎如图片。
A theme can include its own theme engine, it can use an existing theme engine, such as the Pixbuf theme which draws all elements in terms of images, or it can use GTK+'s built in drawing code.
GTK+程序启动如何分析主题?
每一个GTK+的程序都会在启动时分析当前主题的gtkrc文件来决定显示控件的风格,在gtkrc文件中通常会定义一个theme engine,并给它传递适当的参数,例如
engine "crux-engine" {
rect_scrollbar = TRUE
}
theme engine以共享库的形式存在,存放在/usr/lib/gtk-2.0/2.2.0/engines或/usr/lib/gtk/themes/engines下,文件名形式为libcrux-engine.so.
我们看在实施题材引擎的有些细节。 如上所述,题材引擎是一个共有的对象。 共有的对象必须出口三个入口:
(1)void theme_init (GtkThemeEngine *engine);
(2)void theme_exit (GtkThemeEngine *engine);
(3)GtkRcStyle *theme_create_rc_style (GtkThemeEngine *engine);
重点:
1,在theme_init函数主要执行以下两个函数,注册生成GtkRCStyle和GtkStyle类。
crux_rc_style_register_type (module);
crux_style_register_type (module);
-----crux_rc_style_register_type函数执行GtkRCStyle类的初始化函数,重载crux_parse_rc_style和crux_rc_style_merge函数,用于gtkrc文件中参数的提取分析。
同样地,crux_style_register_type函数执行GtkStyle类的初始化函数,重载所有drawing functions,例如
static void crux_style_class_init (PixbufStyleClass *klass)
{
GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
style_class->draw_hline = draw_hline;
style_class->draw_vline = draw_vline;
style_class->draw_shadow = draw_shadow;
style_class->draw_polygon = draw_polygon;
style_class->draw_arrow = draw_arrow;
style_class->draw_diamond = draw_diamond;
这些主题引擎通过对这些作用中的每一个的GtkThemeEngin的描述,是GTK+为每个题材引擎模块创造它装载的对象。
如何安装主题引擎
我们现在常用的发行版都对主题引擎进行了打包,并与Gnome中的已经存在的引擎一起装载。
对其主题引擎使用下面的命名方案:gtk-engines-(GTK+ 1.2的引擎)和 gtk2-engines-(GTK+ 2.4 的引擎)。先检查所使用的发行版的引擎,如果有,直接使用它。
如果所用的发行版没有您想要的主题引擎,那么可以使用标准包的安装方法来安装。大多数引擎使用的是 atuoconf 和 make install。这样安装就非常简单了:./configure && make && make install 。一般在readme中有详细的说明引擎如何安装。
引擎和主题如何区分?
我个人觉得,引擎其实只是一个程序,主题的配置文件就是是这个程序的参数,而这个程序运行的结果就是主题的外观。
(4)、GTK+简介
1、GTK+(GIMP ToolKit,GIMP工具包)最初用于开发GIMP,是一个用于创建图形用户接口的图形库在功能上类似微软的MFC,即为应用程序提供一套与平台无关 的图形用户界面接口GTK+是基于LGPL授权的,因此GTK+在开发开源软件或商业的非自由软件领域中都得到越来越广泛的使用特别在嵌入式应用中,由于 GTK+库小,且程序员可以根据自己需要对其进行裁剪,因此其占用资源少并能快速装入,所以基于GTK+开发的图形用户界面适合在内存受限的嵌入式设备上 运行
2、GTK+是在GDK的基础上创建的,其软件层次结构如图1所示Glib是Linux系统下最常用的轻量级的C语言函数库,它提供了C常用的数据结构定义、处理函数、宏、
3、(引入)如果定义组件的风格
定义组合构件的设计首先需要对GTK+自定义构件的设计非常熟悉,对GTK+构件的设计风格和继承关系很了解,并且能掌握对各个库的相应关系组合构件它不 是单纯从某个构件继承下来的,只是组合任何想要组合的构件来实现某项功能因此必须考虑该组合构件的父类问题组合构件也跟构件库里面的构件一样,它也可能要 接收信号并做出相应的处理因此挂接信号也是设计需要考虑的问题作为一个构件,组合构件也应有自己的风格,由于组合构件是多个构件的组合,每个构件又有其不 同的风格,如何确定当前构件的风格也是设计的难点
组合构件的设计思想及其实现
1、组合构件的设计思想
通俗的讲,GTK+的构件库是基于C语言的,它不具有面向对象的特性,然而GTK+的确又是面向对象的,那是因为它用C语言来实现了C++编译器的功能因 此它同样具有继承的特性,它的代码风格也延续了面向对象的设计风格在GTK+库中,直接继承自GtkObject对象的构件主要是GtkWidget,它 几乎是所有可视构件的共同祖先,大多数构件共有的属性都包括在其中与其他GUI开发工具不同的是,我们不用直接创建GtkObject或 GtkWidget对象,而是用定义对象的实例结构和类结构的方式来定义对象,然后再通过类型注册来实现对象当前笔者就根据组合构件的特点,直接从 GtkObject继承它与GtkWidget是一种并行关系和其他构件一样,它也有相应的宏定义,来进行各种强制转换和类型获取任何一个构件都有其创建 对象函数,组合构件也是一样,在对象中定义各个成员构件,在创建对象时将其一一创建,并根据需要对其各个构件来进行属性设定,最后返回的是组合构件对象本 身关于信号的设定也是和其他构件的方法一样,在类的结构体中定义信号,并在类的初始化中对信号进行定义组合构件的接口设计应可以根据当前总体设计的需要, 而不是像一般构件一样完全的独立出来,它具有自己的特色,并不需要刻意遵守一般构件的要求这也是组合构件的灵活性所在GTK+允许用户通过rc文件来定制 应用程序的主题风格,即设置构件颜色、字号大小,并为构件添加背景图标等而对于组合构件而言,由于其为多个构件的组合,每个构件都有其相应的风格设计,因 此严格的讲它本身是不具有风格设计的,所谓组合构件的风格设计,就是对各个构件进行风格设计,并将其风格设定封装在一个函数里,对外只提供一个接口对于组 合构件如果不进行风格设计,它将沿用整个图形界面的风格设计。
(5)、项目中GTK主题文件实例
*************************************************************
style "my_font_style" {
fg[NORMAL] = "#ffffff" #窗口文字颜色:白
bg[NORMAL] = "#666666" #窗口底色:灰白
font_name = "fzheiti 20"
}
widget "GtkWidget*" style "my_font_style"
#style "my_window_style" {
# engine "pixmap" {
# image {
# function = FLAT_BOX
# recolorable = TRUE
# stretch = TRUE
# file = "../pixmaps/olderpc_desktop/neoshine-default.jpg"
# }
# }
#}
#widget "window" style "my_window_style"
#style "fixed" {
# bg_pixmap[NORMAL] = "<parent>"
# bg_pixmap[INSENSITIVE]="<parent>"
# bg_pixmap[ACTIVE]="<parent>"
# bg_pixmap[PRELIGHT]="<parent>"
#}
#widget "win.fixed" style "fixed"
style "my_button_style" {
engine "pixmap" {
# image {
# function = BOX
# recolorable = TRUE
# state = PRELIGHT
# stretch = TRUE
# file = "../pixmaps/olderpc_desktop/main_button_light.png"
# }
image {
function = FOCUS #当控件获得焦点的时候,使用下面得图片
overlay_file = "../pixmaps/olderpc_desktop/main_button_light.png"
}
image {
function = BOX
recolorable = TRUE
# state = NORMAL
stretch = TRUE
file = "../pixmaps/olderpc_desktop/main_button.png"
}
}
# bg_pixmap[NORMAL] = "../pixmaps/olderpc_desktop/main_button.png"
}
widget "GtkButton*" style "my_button_style"
# Setting default font style
class "GtkWidget" style "my_font_style"
class "GtkWidget" style "my_button_style"
*************************************************************
(1)、GTK 主题指南
1.Widgets
GTK拥有一套大量的widget集合,如按钮,滚动条,编辑框等,每一种组件的属性都可以单独进行配置。
所有的widget由GtkWidget派生出来的。也就是说,更改GtkWidget的属性所有的widgets会受到影响。幸运的是,大多数widget有其父类,如GtkButton的属性同样使GtkCheckButton生效,除非你对其进行单独的配制。
widgets, 一些常用元素:/GnomePanel /GtkButton /GtkCheckButton /GtkColorButton /GtkComboBox /GtkComboBoxEntry /GtkEntry /GtkFrame /GtkMenu /GtkMenuBar /GtkMenuItem /GtkNotebook /GtkProgressBar /GtkRadioButton /GtkScale /GtkSpinButton /GtkStatusbar /GtkTreeView /StyleProperties /SymbolicColors
2.Styles
用户自定义GtkWidget形成自己的风格,定义的方式有两种形式,一种是以使用Gtk中的style,但style定义方式中只给出了几种有限风格属 性,如设置滚动条的宽度。另一种就是通过使用engine这种机制来实现,其中定义很多的属性可供使用时选择。
通过定义不同的styles合并在一起成为一个最终的Gtk主题,所以通常可以定义出一个基本的风格,其包含一此通用的选项配置,对于定义组件专有的属性可以在引用它的基础上做设置,如颜色的修改.
3.Engines
与styles组合实现出更有吸引力的风格,gtk内部实现很多可供选择的风格。
4.gtkrc文件
一个rc文件被称为gtkrc,存放的地方取决于系统的配置,通常放在/usr/share/themes/themename目录下,存在gtk-2.0/gtkrc文件,此文件可以是一个rc文件,里面定义了gtk中各种组件的配置。
1)修改构件的属性:
fg:设置一个构件的前景色
bg:设置一个构件的背景色
text:可编辑文本构件的前景色
base:可编辑文本构件的背景色
bg_pixmap:显示像素图的构件的背景色
font_name:设置字体风格
xthickness:设置左右边界的宽度
ythickness:设置上下边界宽度
2)每一构件的分为五种状态:
NORMAL:鼠标没有覆盖,点击的状态
PRELIGHT:鼠标在组件之上
ACTIVE:鼠标被按下或点击的状态,
INSENSITIVE:不能被激活,或点击的状态
SELECTED:被选对象可以带好多属性
3)风格绑定:
1.将一种风格绑定到组件类
格式:class "GtkButton" style "my-button" 将“my-button"风格绑定到GtkButton的所有实例
widget_class "*Text*" style "bright_yellow"
将"bright_yellow"风格绑定到名字中含有“Text“的组件
2.组件嵌套的方式widget_class
如widget_class "*.GtkButton.*" style "button-content"
3.应用指定风格
如果一个应用开发者已经明确陈列一种元素,在gtkrc文件中指明元素名,来将它风格化。
eg: widget “funky bar“ style “mystyle“
4.风格绑定的优先次序
对widget的rc风格绑定 > 对widget_class风格的绑定 > class 同一种组件的多种声明是,后一种优于前一种。指定优先的highest,rc,theme,application,gtk,lowest将覆盖上述的风 格绑定,
4)组件指定风格:
gtk api文档列表中,列出的style properties,对某种widget类型,是明确的,eg。GtkWiget::focus-line-width = 2
5)高级指定风格(依据gtk2正式文档):
界定符#,注释所在行的内容,在解析gtkrc文件时,将此行被忽略掉。
1.binding name {...} 声明绑定设置
2.calss pattern [ style | binding [ : priority ]] name 对继承层的一个具体的分支,指定风格或绑定设置
3.include finename: 在此处引入文件,如果不是包含绝对路径的文件名,将会在当前打开rc文件的文件夹下,搜索此文件
4.module_path path: 设置搜索rc文件中涉及的主题引擎路径。
5.pixmap_path path: 设置搜索像素图的路径。
6.widget pattern [ style | binding [ : priority ]] name 给路径名上相配匹配的一组具体的组件设置风格或绑定。
7.widget_class pattern [ style | binding [ : priority ]] nane 给路径名上相匹配的一组具体的组件设置风格或绑定。
5.widget设置示例:
* Buttons:
buttons不存在背景的设置,只能通过对其所处的widget上添加背景的处理。
bevelling (relief): 对button进行三种状态的设置: GTK_RELIEF_NORMAL, GTK_RELIEF_HALF, GTK_RELIEF_NONE.
* Labels:
不存在背景色,估计可以通过text[]这一属性设置其前景色
* Text Boxes:
背景: base[NORMAL]
文本颜色: text[NORMAL]
应用自定义的风格: widget_class "*TextView*" style "my_style"
改变编辑时光标的颜色eg: GtkWidget::cursor-color "red"
* Scrollbars and Scales:
使用 widget_class "*Scrollbar*" 来指定scrollbars.
arrow button and main draggable rectangle colour is controlled by bg[NORMAL]
槽和边框设置背景色 bg[ACTIVE]
鼠标光标移动scrollbar(滚动条)上时的颜色使用bg[PRELIGHT]设置
光标箭头的颜色fg[NORMAL]
* Combobox: http://live.gnome.org/GnomeArt/Tutorials/GtkThemes/GtkComboBox
combobox是一个按钮包含:label, separator, and arrow
* Icons:
设置自定义的图标
stock["my-stock-item"] =
{
{ "itemmenusize.png", *, *, "gtk-menu" },
{ "itemtoolbarsize.png", *, *, "gtk-large-toolbar" }
{ "itemgeneric.png" } /* implicit *, *, * as a fallback */
}
* Menus:
菜单是一个组合控件,包括menubar和menuitems.
* Lists:
与Treeview组合为一个整体.
* Treeview:
Treeview开为两部分:head_window,bin_window,该组件可以按元素列表和树的形式显示
Treeview 背景色是通过base[]控制,如果处于非关注状态则按base[ACTIVE]的着色显示.
设置Treeview的列的顶部的颜色,使用bg控制.
Treeview列的顶部为一个按钮. 指定widget_class "*TreeView.GtkButton*". 指定顶部文本的颜色The text colour in the heads is controlled with fg, and not text.
The default line spacing of TreeView lists is quite large. It is not possible to reduce it in the rc file. This is a known issue.
Treeview 风格自属性有: allow-rules, even-row-color, expander-size, horizontal-separator, indent-expanders, odd-row-color, vertical-separator.
* Tabs:
文本内容在非选中的tab上使用的是fg[ACTIVE],背景色设置bg[ACTIVE].
定义tabs文本设置 widget_class "*GtkNotebook*GtkLabel".
* engine
gtk engines 给开发者提供大量不同的显示风格选项。通过使用不同的engine来设置不同风格的组件。
style "some-style" {
engine "clearlooks" {
# engine specific settings go here
}
}
颜 色可以使用颜色的名称(GTK+ knows all names from the X color database /usr/lib/X11/rgb.txt),使用一种16进制的形式例如#rrrrggggbbbb, #rrrgggbbb, #rrggbb, or #rgb。r,g,b是16进制的整数(0-65535)或者是浮点数字0.0-1.0。
从2.10开始颜色可以使用符号颜色 以@color-name 或者是用表达式合成颜色。
(2)、如何从开始理解gtkrc在实践中的使用
GTK 有自己缺省处理应用程序的方法,这就是使用rc配置文件。这些文件可用于给几乎任何构件设置颜色,也能为一些构件的背景贴上一幅像素图。
rc 文件的功能
在你的应用程序开始处,应包含一个如下的函数调用:
void gtk_rc_parse( char *filename );
把 rc 文件名传递给被调用的函数,随后 GTK 会解析这个文件,并且使用文件中所定义构件类型的风格设置。
如果希望定义一套和其它构件集或同一构件集中其它逻辑部分具有不同风格的特定构件集,使用以下函数调用:
void gtk_widget_set_name( GtkWidget *widget, gchar *name );
把新创建的构件作为第一个参数,把你给该构件定的名程作为第二个参数。这使你能够在 rc 文件中按名称更改这个构件的属性。
如果我们使用了一个如下的函数调用:
button = gtk_button_new_with_label ("redred");
gtk_widget_set_name (button,"redred");
那么这个按钮取名为"redred",并且在 rc 文件中可能通过像"redred button.GtkButton"这样的名称找到它。
后面作为示例的 rc 文件,设置主窗口的属性,告诉所有子窗口继承在"main button"风格项中规定的风格。在应用程序中的代码为:
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name (window, "main window");
然后在 rc 文件中用如下一行定义它的风格:
widget "main window.*GtkButton*" style "main_button"
该定义把"主窗口"中的所有按钮构件设置为 rc 文件中定义的"main_buttons"风格。
如你所见,这是一个非常强大和灵活的系统。如何最大限度的利用它的优势需要使用你的想象力。)
(3)、背景介绍
什么是gtk主题引擎?
主题引擎是应用程序主题使用的一些代码。如今,已有许多不同的主题引擎存在。GTK + 主题由三件事: 一个主题引擎 ,这是一个共享对象包括代码的图形要素,一个配置文件来配置的运作主题的引擎和核心部分基于GTK +和额外的数据文件的主题引擎如图片。
A theme can include its own theme engine, it can use an existing theme engine, such as the Pixbuf theme which draws all elements in terms of images, or it can use GTK+'s built in drawing code.
GTK+程序启动如何分析主题?
每一个GTK+的程序都会在启动时分析当前主题的gtkrc文件来决定显示控件的风格,在gtkrc文件中通常会定义一个theme engine,并给它传递适当的参数,例如
engine "crux-engine" {
rect_scrollbar = TRUE
}
theme engine以共享库的形式存在,存放在/usr/lib/gtk-2.0/2.2.0/engines或/usr/lib/gtk/themes/engines下,文件名形式为libcrux-engine.so.
我们看在实施题材引擎的有些细节。 如上所述,题材引擎是一个共有的对象。 共有的对象必须出口三个入口:
(1)void theme_init (GtkThemeEngine *engine);
(2)void theme_exit (GtkThemeEngine *engine);
(3)GtkRcStyle *theme_create_rc_style (GtkThemeEngine *engine);
重点:
1,在theme_init函数主要执行以下两个函数,注册生成GtkRCStyle和GtkStyle类。
crux_rc_style_register_type (module);
crux_style_register_type (module);
-----crux_rc_style_register_type函数执行GtkRCStyle类的初始化函数,重载crux_parse_rc_style和crux_rc_style_merge函数,用于gtkrc文件中参数的提取分析。
同样地,crux_style_register_type函数执行GtkStyle类的初始化函数,重载所有drawing functions,例如
static void crux_style_class_init (PixbufStyleClass *klass)
{
GtkStyleClass *style_class = GTK_STYLE_CLASS (klass);
style_class->draw_hline = draw_hline;
style_class->draw_vline = draw_vline;
style_class->draw_shadow = draw_shadow;
style_class->draw_polygon = draw_polygon;
style_class->draw_arrow = draw_arrow;
style_class->draw_diamond = draw_diamond;
这些主题引擎通过对这些作用中的每一个的GtkThemeEngin的描述,是GTK+为每个题材引擎模块创造它装载的对象。
如何安装主题引擎
我们现在常用的发行版都对主题引擎进行了打包,并与Gnome中的已经存在的引擎一起装载。
对其主题引擎使用下面的命名方案:gtk-engines-(GTK+ 1.2的引擎)和 gtk2-engines-(GTK+ 2.4 的引擎)。先检查所使用的发行版的引擎,如果有,直接使用它。
如果所用的发行版没有您想要的主题引擎,那么可以使用标准包的安装方法来安装。大多数引擎使用的是 atuoconf 和 make install。这样安装就非常简单了:./configure && make && make install 。一般在readme中有详细的说明引擎如何安装。
引擎和主题如何区分?
我个人觉得,引擎其实只是一个程序,主题的配置文件就是是这个程序的参数,而这个程序运行的结果就是主题的外观。
(4)、GTK+简介
1、GTK+(GIMP ToolKit,GIMP工具包)最初用于开发GIMP,是一个用于创建图形用户接口的图形库在功能上类似微软的MFC,即为应用程序提供一套与平台无关 的图形用户界面接口GTK+是基于LGPL授权的,因此GTK+在开发开源软件或商业的非自由软件领域中都得到越来越广泛的使用特别在嵌入式应用中,由于 GTK+库小,且程序员可以根据自己需要对其进行裁剪,因此其占用资源少并能快速装入,所以基于GTK+开发的图形用户界面适合在内存受限的嵌入式设备上 运行
2、GTK+是在GDK的基础上创建的,其软件层次结构如图1所示Glib是Linux系统下最常用的轻量级的C语言函数库,它提供了C常用的数据结构定义、处理函数、宏、
3、(引入)如果定义组件的风格
定义组合构件的设计首先需要对GTK+自定义构件的设计非常熟悉,对GTK+构件的设计风格和继承关系很了解,并且能掌握对各个库的相应关系组合构件它不 是单纯从某个构件继承下来的,只是组合任何想要组合的构件来实现某项功能因此必须考虑该组合构件的父类问题组合构件也跟构件库里面的构件一样,它也可能要 接收信号并做出相应的处理因此挂接信号也是设计需要考虑的问题作为一个构件,组合构件也应有自己的风格,由于组合构件是多个构件的组合,每个构件又有其不 同的风格,如何确定当前构件的风格也是设计的难点
组合构件的设计思想及其实现
1、组合构件的设计思想
通俗的讲,GTK+的构件库是基于C语言的,它不具有面向对象的特性,然而GTK+的确又是面向对象的,那是因为它用C语言来实现了C++编译器的功能因 此它同样具有继承的特性,它的代码风格也延续了面向对象的设计风格在GTK+库中,直接继承自GtkObject对象的构件主要是GtkWidget,它 几乎是所有可视构件的共同祖先,大多数构件共有的属性都包括在其中与其他GUI开发工具不同的是,我们不用直接创建GtkObject或 GtkWidget对象,而是用定义对象的实例结构和类结构的方式来定义对象,然后再通过类型注册来实现对象当前笔者就根据组合构件的特点,直接从 GtkObject继承它与GtkWidget是一种并行关系和其他构件一样,它也有相应的宏定义,来进行各种强制转换和类型获取任何一个构件都有其创建 对象函数,组合构件也是一样,在对象中定义各个成员构件,在创建对象时将其一一创建,并根据需要对其各个构件来进行属性设定,最后返回的是组合构件对象本 身关于信号的设定也是和其他构件的方法一样,在类的结构体中定义信号,并在类的初始化中对信号进行定义组合构件的接口设计应可以根据当前总体设计的需要, 而不是像一般构件一样完全的独立出来,它具有自己的特色,并不需要刻意遵守一般构件的要求这也是组合构件的灵活性所在GTK+允许用户通过rc文件来定制 应用程序的主题风格,即设置构件颜色、字号大小,并为构件添加背景图标等而对于组合构件而言,由于其为多个构件的组合,每个构件都有其相应的风格设计,因 此严格的讲它本身是不具有风格设计的,所谓组合构件的风格设计,就是对各个构件进行风格设计,并将其风格设定封装在一个函数里,对外只提供一个接口对于组 合构件如果不进行风格设计,它将沿用整个图形界面的风格设计。
(5)、项目中GTK主题文件实例
*************************************************************
style "my_font_style" {
fg[NORMAL] = "#ffffff" #窗口文字颜色:白
bg[NORMAL] = "#666666" #窗口底色:灰白
font_name = "fzheiti 20"
}
widget "GtkWidget*" style "my_font_style"
#style "my_window_style" {
# engine "pixmap" {
# image {
# function = FLAT_BOX
# recolorable = TRUE
# stretch = TRUE
# file = "../pixmaps/olderpc_desktop/neoshine-default.jpg"
# }
# }
#}
#widget "window" style "my_window_style"
#style "fixed" {
# bg_pixmap[NORMAL] = "<parent>"
# bg_pixmap[INSENSITIVE]="<parent>"
# bg_pixmap[ACTIVE]="<parent>"
# bg_pixmap[PRELIGHT]="<parent>"
#}
#widget "win.fixed" style "fixed"
style "my_button_style" {
engine "pixmap" {
# image {
# function = BOX
# recolorable = TRUE
# state = PRELIGHT
# stretch = TRUE
# file = "../pixmaps/olderpc_desktop/main_button_light.png"
# }
image {
function = FOCUS #当控件获得焦点的时候,使用下面得图片
overlay_file = "../pixmaps/olderpc_desktop/main_button_light.png"
}
image {
function = BOX
recolorable = TRUE
# state = NORMAL
stretch = TRUE
file = "../pixmaps/olderpc_desktop/main_button.png"
}
}
# bg_pixmap[NORMAL] = "../pixmaps/olderpc_desktop/main_button.png"
}
widget "GtkButton*" style "my_button_style"
# Setting default font style
class "GtkWidget" style "my_font_style"
class "GtkWidget" style "my_button_style"
*************************************************************