Widget Overview
在GTK中使用能够正常工作的widget,通常包含以下几个步骤
- gtk_*_new()函数 创建一个静态的widget 。
- 为创建的widget设置需要拦截的信号或者事件,以及设置此信号的处理函数。
- 为widget设置属性。
- 对widget进行打包。
- 让widget显示出来。
这几个步骤不一定全部都会有。
下面的树形结构显示了各个数据结构之间的层级关系。
GObject
|
GtkObject
+GtkWidget
| +GtkMisc
| | +GtkLabel
| | | `GtkAccelLabel
| | +GtkArrow
| | `GtkImage
| +GtkContainer
| | +GtkBin
| | | +GtkAlignment
| | | +GtkFrame
| | | | `GtkAspectFrame
| | | +GtkButton
| | | | +GtkToggleButton
| | | | | `GtkCheckButton
| | | | | `GtkRadioButton
| | | | `GtkOptionMenu
| | | +GtkItem
| | | | +GtkMenuItem
| | | | +GtkCheckMenuItem
| | | | | `GtkRadioMenuItem
| | | | +GtkImageMenuItem
| | | | +GtkSeparatorMenuItem
| | | | `GtkTearoffMenuItem
| | | +GtkWindow
| | | | +GtkDialog
| | | | | +GtkColorSelectionDialog
| | | | | +GtkFileSelection
| | | | | +GtkFontSelectionDialog
| | | | | +GtkInputDialog
| | | | | `GtkMessageDialog
| | | | `GtkPlug
| | | +GtkEventBox
| | | +GtkHandleBox
| | | +GtkScrolledWindow
| | | `GtkViewport
| | +GtkBox
| | | +GtkButtonBox
| | | | +GtkHButtonBox
| | | | `GtkVButtonBox
| | | +GtkVBox
| | | | +GtkColorSelection
| | | | +GtkFontSelection
| | | | `GtkGammaCurve
| | | `GtkHBox
| | | +GtkCombo
| | | `GtkStatusbar
| | +GtkFixed
| | +GtkPaned
| | | +GtkHPaned
| | | `GtkVPaned
| | +GtkLayout
| | +GtkMenuShell
| | | +GtkMenuBar
| | | `GtkMenu
| | +GtkNotebook
| | +GtkSocket
| | +GtkTable
| | +GtkTextView
| | +GtkToolbar
| | `GtkTreeView
| +GtkCalendar
| +GtkDrawingArea
| | `GtkCurve
| +GtkEditable
| | +GtkEntry
| | `GtkSpinButton
| +GtkRuler
| | +GtkHRuler
| | `GtkVRuler
| +GtkRange
| | +GtkScale
| | | +GtkHScale
| | | `GtkVScale
| | `GtkScrollbar
| | +GtkHScrollbar
| | `GtkVScrollbar
| +GtkSeparator
| | +GtkHSeparator
| | `GtkVSeparator
| +GtkInvisible
| +GtkPreview
| `GtkProgressBar
+GtkAdjustment
+GtkCellRenderer
| +GtkCellRendererPixbuf
| +GtkCellRendererText
| +GtkCellRendererToggle
+GtkItemFactory
+GtkTooltips
`GtkTreeViewColumn
Writing your Own Widget
The Anatony Of A Widget
GTK widget的设计使用的是OO的思想,但是,却是用C语言来实现的。对属于一类的所有widget的实例(例如所有的Button),他们共有的信息存储在他们所属的类的结构里。为了实现类之间的继承,类结构体的第一个成员必须是此类的父结构体。 例如GtkButton的类的定义,如下:
struct _GtkButtonClass
{
GtkContainerClass parent_class;
void (* pressed) (GtkButton *button);
void (* released) (GtkButton *button);
void (* clicked) (GtkButton *button);
void (* enter) (GtkButton *button);
void (* leave) (GtkButton *button);
};
并且,类结构只存储一份。还有一个结构体,每个类的实例化都会对应一个。此结构体用于存储每个实例化对象所特有的信息。对于Button类来说,此结构如下:
struct _GtkButton
{
GtkContainer container;
GtkWidget *child;
guint in_button : 1;
guint button_down : 1;
};
我们称这个结构体为对象结构体,与类结构体类似,它的第一个成员是其父类所对应的对象结构体。