⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sec-creatingacompositewidget.html

📁 gtk的教材和问答集
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<HTML><HEAD><TITLE>Creating a Composite widget</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.49"><LINKREL="HOME"TITLE="GTK+ 1.2 Tutorial"HREF="gtk-tut.html"><LINKREL="UP"TITLE="Writing Your Own Widgets"HREF="ch-writingyourownwidgets.html"><LINKREL="PREVIOUS"TITLE="The Anatomy Of A Widget"HREF="sec-theanatomyofawidget.html"><LINKREL="NEXT"TITLE="Creating a widget from scratch"HREF="sec-creatingawidgetfromscratch.html"></HEAD></head><body bgcolor="#FFFFFF" marginheight=0 marginwidth=0 width="100%"><table cellspacing=6 border=0 cellpadding=0 width="100%">  <tr>    <td bgcolor="#FFFFFF" valign=top nowrap>    <centeR><A HREF="/"><img src="/images/gtk-logo-rgb.gif" width=107 height=140 border=0></A>      <font face="helvetica,lucidia" color="#000000"><BR><BR><b>GTK+<BR>The GIMP Toolkit</b></center><BR><table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B>General</B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="/">Introduction</A><BR><A HREF="/screenshots/">Screenshots</A><br><A HREF="/download/">Download</A><br><A HREF="/mailinglists.html">Mailing Lists</A><BR><A HREF="/bindings.html">Language Bindings</A><BR><A HREF="http://gtk.themes.org/">Themes</A><BR><A HREF="/bugs.html">Bug Tracker</A><BR></td></tr></table></td></tr></table><BR>  <table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B>Documentation</B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="/faq/">FAQ</A><br><A HREF="/tutorial/">Tutorial</A><BR><A HREF="/api/">API Reference</A><br><A HREF="/books.html">Published Books</A><BR></td></tr></table></td></tr></table><BR>  <table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B>Projects</B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="http://www.pango.org/">Pango</A><BR><A HREF="http://sources.redhat.com/inti/">Inti</A><BR><A HREF="http://www.gnome.org/">GNOME</A><BR><A HREF="http://user.sgic.fi/~tml/gimp/win32/">GTK+ for Win32</A><br><A HREF="http://people.redhat.com/sopwith/gtkfb/">GtkFB (Framebuffer)</A><br><A HREF="http://www.directfb.org/gtk.xml">GTK+ on DirectFB</A><BR><A HREF="/beos/">GTK+ for BeOS</A></td></tr></table></td></tr></table><BR>  <table width=100% cellspacing=0 cellpadding=2 border=0><tr><td bgcolor="#000000"><table width=100% cellspacing=0 cellpadding=4 border=0><tr><td bgcolor="#AAAAEE" nowrap><B><B>Applications</B></B></td></tr><tr><td bgcolor="#FFFFFF" nowrap><A HREF="http://www.gimp.org/">GIMP</A><BR><A HREF="http://www.abiword.org/">Abiword</A><BR><A HREF="http://www.lysator.liu.se/~alla/dia/dia.html">Dia</A><BR><A HREF="http://glade.pn.org/">Glade</A><BR><A HREF="http://www.gnucash.org/">GnuCash</A><BR><A HREF="http://www.gnome.org/projects/gnumeric/">Gnumeric</A><BR><BR><A HREF="http://www.gnome.org/applist/">GNOME Software Map</A><br></td></tr></table></td></tr></table><BR>      </td>  <td bgcolor="#ffffff" valign=top width="99%"><font face="lucida,helvetica"><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLEWIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GTK+ 1.2 Tutorial</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><AHREF="sec-theanatomyofawidget.html">&#60;&#60;&#60; Previous</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 24. Writing Your Own Widgets</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="sec-creatingawidgetfromscratch.html">Next &#62;&#62;&#62;</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="SEC-CREATINGACOMPOSITEWIDGET">24.3. Creating a Composite widget</A></H1><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2569">24.3.1. Introduction</A></H2><P>One type of widget that you may be interested in creating is awidget that is merely an aggregate of other GTK widgets. This type ofwidget does nothing that couldn't be done without creating newwidgets, but provides a convenient way of packaging user interfaceelements for reuse. The FileSelection and ColorSelection widgets inthe standard distribution are examples of this type of widget.</P><P>The example widget that we'll create in this section is the Tictactoewidget, a 3x3 array of toggle buttons which triggers a signal when allthree buttons in a row, column, or on one of the diagonals aredepressed. </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2573">24.3.2. Choosing a parent class</A></H2><P>The parent class for a composite widget is typically the containerclass that holds all of the elements of the composite widget. Forexample, the parent class of the FileSelection widget is theDialog class. Since our buttons will be arranged in a table, itmight seem natural to make our parent class the Tableclass. Unfortunately, this turns out not to work. The creation of awidget is divided among two functions - a <TTCLASS="LITERAL">WIDGETNAME_new()</TT>function that the user calls, and a <TTCLASS="LITERAL">WIDGETNAME_init()</TT> functionwhich does the basic work of initializing the widget which isindependent of the arguments passed to the <TTCLASS="LITERAL">_new()</TT>function. Descendant widgets only call the <TTCLASS="LITERAL">_init</TT> function oftheir parent widget. But this division of labor doesn't work well fortables, which when created need to know the number of rows andcolumns in the table. Unless we want to duplicate most of thefunctionality of <TTCLASS="LITERAL">gtk_table_new()</TT> in our Tictactoe widget, we hadbest avoid deriving it from Table. For that reason, we derive itfrom VBox instead, and stick our table inside the VBox.</P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2581">24.3.3. The header file</A></H2><P>Each widget class has a header file which declares the object andclass structures for that widget, along with public functions. A couple of features are worth pointing out. To prevent duplicatedefinitions, we wrap the entire header file in:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">#ifndef __TICTACTOE_H__#define __TICTACTOE_H__...#endif /* __TICTACTOE_H__ */</PRE></TD></TR></TABLE><P>And to keep C++ programs that include the header file happy, in:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">#ifdef __cplusplusextern "C" {#endif /* __cplusplus */...#ifdef __cplusplus}#endif /* __cplusplus */</PRE></TD></TR></TABLE><P>Along with the functions and structures, we declare three standardmacros in our header file, <TTCLASS="LITERAL">TICTACTOE(obj)</TT>,<TTCLASS="LITERAL">TICTACTOE_CLASS(klass)</TT>, and <TTCLASS="LITERAL">IS_TICTACTOE(obj)</TT>, which cast apointer into a pointer to the object or class structure, and checkif an object is a Tictactoe widget respectively.</P><P>Here is the complete header file:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">/* tictactoe.h */#ifndef __TICTACTOE_H__#define __TICTACTOE_H__#include &#60;gdk/gdk.h&#62;#include &#60;gtk/gtkvbox.h&#62;#ifdef __cplusplusextern "C" {#endif /* __cplusplus */#define TICTACTOE(obj)          GTK_CHECK_CAST (obj, tictactoe_get_type (), Tictactoe)#define TICTACTOE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, tictactoe_get_type (), TictactoeClass)#define IS_TICTACTOE(obj)       GTK_CHECK_TYPE (obj, tictactoe_get_type ())typedef struct _Tictactoe       Tictactoe;typedef struct _TictactoeClass  TictactoeClass;struct _Tictactoe{  GtkVBox vbox;    GtkWidget *buttons[3][3];};struct _TictactoeClass{  GtkVBoxClass parent_class;  void (* tictactoe) (Tictactoe *ttt);};guint          tictactoe_get_type        (void);GtkWidget*     tictactoe_new             (void);void	       tictactoe_clear           (Tictactoe *ttt);#ifdef __cplusplus}#endif /* __cplusplus */#endif /* __TICTACTOE_H__ */</PRE></TD></TR></TABLE></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2593">24.3.4. The <TTCLASS="LITERAL">_get_type()</TT> function</A></H2><P>We now continue on to the implementation of our widget. A corefunction for every widget is the function<TTCLASS="LITERAL">WIDGETNAME_get_type()</TT>. This function, when first called, tellsGTK about the widget class, and gets an ID that uniquely identifiesthe widget class. Upon subsequent calls, it just returns the ID.</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">guinttictactoe_get_type (){  static guint ttt_type = 0;  if (!ttt_type)    {      GtkTypeInfo ttt_info =      {	"Tictactoe",	sizeof (Tictactoe),	sizeof (TictactoeClass),	(GtkClassInitFunc) tictactoe_class_init,	(GtkObjectInitFunc) tictactoe_init,	(GtkArgSetFunc) NULL,        (GtkArgGetFunc) NULL      };      ttt_type = gtk_type_unique (gtk_vbox_get_type (), &#38;ttt_info);    }  return ttt_type;}</PRE></TD></TR></TABLE><P>The GtkTypeInfo structure has the following definition:</P><TABLEBORDER="0"BGCOLOR="#E0E0E0"WIDTH="100%"><TR><TD><PRECLASS="PROGRAMLISTING">struct _GtkTypeInfo{  gchar *type_name;  guint object_size;  guint class_size;  GtkClassInitFunc class_init_func;  GtkObjectInitFunc object_init_func;  GtkArgSetFunc arg_set_func;  GtkArgGetFunc arg_get_func;};</PRE></TD></TR></TABLE><P>The fields of this structure are pretty self-explanatory. We'll ignorethe <TTCLASS="LITERAL">arg_set_func</TT> and <TTCLASS="LITERAL">arg_get_func</TT> fields here: they have an important, but as yet largelyunimplemented, role in allowing widget options to be conveniently setfrom interpreted languages. Once GTK has a correctly filled in copy ofthis structure, it knows how to create objects of a particular widgettype. </P></DIV><DIVCLASS="SECT2"><H2CLASS="SECT2"><ANAME="AEN2604">24.3.5. The <TTCLASS="LITERAL">_class_init()</TT> function</A></H2><P

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -