亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? gtk_tut-22.html

?? GTK development guide
?? HTML
?? 第 1 頁 / 共 4 頁
字號:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.7">
 <TITLE>GTK v1.2 Tutorial: Writing Your Own Widgets </TITLE>
 <LINK HREF="gtk_tut-23.html" REL=next>
 <LINK HREF="gtk_tut-21.html" REL=previous>
 <LINK HREF="gtk_tut.html#toc22" REL=contents>
</HEAD>
<BODY TEXT="#CCCCCC" BGCOLOR="#000000" LINK="#33cc00" VLINK="#009900" ALINK="#FF0000">
<A HREF="gtk_tut-23.html">Next</A>
<A HREF="gtk_tut-21.html">Previous</A>
<A HREF="gtk_tut.html#toc22">Contents</A>
<HR>
<H2><A NAME="s22">22. Writing Your Own Widgets </A></H2>

<H2><A NAME="ss22.1">22.1 Overview</A>
</H2>

<P>Although the GTK distribution comes with many types of widgets that
should cover most basic needs, there may come a time when you need to
create your own new widget type. Since GTK uses widget inheritance
extensively, and there is already a widget that is close to what you want,
it is often possible to make a useful new widget type in
just a few lines of code. But before starting work on a new widget, check
around first to make sure that someone has not already written
it. This will prevent duplication of effort and keep the number of
GTK widgets out there to a minimum, which will help keep both the code
and the interface of different applications consistent. As a flip side
to this, once you finish your widget, announce it to the world so
other people can benefit. The best place to do this is probably the
<CODE>gtk-list</CODE>.
<P>Complete sources for the example widgets are available at the place you 
got this tutorial, or from:
<P>
<A HREF="http://www.gtk.org/~otaylor/gtk/tutorial/">http://www.gtk.org/~otaylor/gtk/tutorial/</A><P>
<P>
<H2><A NAME="ss22.2">22.2 The Anatomy Of A Widget</A>
</H2>

<P>In order to create a new widget, it is important to have an
understanding of how GTK objects work. This section is just meant as a
brief overview. See the reference documentation for the details. 
<P>GTK widgets are implemented in an object oriented fashion. However,
they are implemented in standard C. This greatly improves portability
and stability over using current generation C++ compilers; however,
it does mean that the widget writer has to pay attention to some of
the implementation details. The information common to all instances of
one class of widgets (e.g., to all Button widgets) is stored in the 
<EM>class structure</EM>. There is only one copy of this in
which is stored information about the class's signals
(which act like virtual functions in C). To support inheritance, the
first field in the class structure must be a copy of the parent's
class structure. The declaration of the class structure of GtkButtton
looks like:
<P>
<BLOCKQUOTE><CODE>
<PRE>
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);
};
</PRE>
</CODE></BLOCKQUOTE>
<P>When a button is treated as a container (for instance, when it is
resized), its class structure can be cast to GtkContainerClass, and
the relevant fields used to handle the signals.
<P>There is also a structure for each widget that is created on a
per-instance basis. This structure has fields to store information that
is different for each instance of the widget. We'll call this
structure the <EM>object structure</EM>. For the Button class, it looks
like:
<P>
<BLOCKQUOTE><CODE>
<PRE>
struct _GtkButton
{
  GtkContainer container;

  GtkWidget *child;

  guint in_button : 1;
  guint button_down : 1;
};
</PRE>
</CODE></BLOCKQUOTE>
<P>Note that, similar to the class structure, the first field is the
object structure of the parent class, so that this structure can be
cast to the parent class' object structure as needed.
<P>
<H2><A NAME="ss22.3">22.3 Creating a Composite widget</A>
</H2>

<H3>Introduction</H3>

<P>One type of widget that you may be interested in creating is a
widget that is merely an aggregate of other GTK widgets. This type of
widget does nothing that couldn't be done without creating new
widgets, but provides a convenient way of packaging user interface
elements for reuse. The FileSelection and ColorSelection widgets in
the standard distribution are examples of this type of widget.
<P>The example widget that we'll create in this section is the Tictactoe
widget, a 3x3 array of toggle buttons which triggers a signal when all
three buttons in a row, column, or on one of the diagonals are
depressed. 
<P>
<H3>Choosing a parent class</H3>

<P>The parent class for a composite widget is typically the container
class that holds all of the elements of the composite widget. For
example, the parent class of the FileSelection widget is the
Dialog class. Since our buttons will be arranged in a table, it
might seem natural to make our parent class the Table
class. Unfortunately, this turns out not to work. The creation of a
widget is divided among two functions - a <CODE>WIDGETNAME_new()</CODE>
function that the user calls, and a <CODE>WIDGETNAME_init()</CODE> function
which does the basic work of initializing the widget which is
independent of the arguments passed to the <CODE>_new()</CODE>
function. Descendant widgets only call the <CODE>_init</CODE> function of
their parent widget. But this division of labor doesn't work well for
tables, which when created need to know the number of rows and
columns in the table. Unless we want to duplicate most of the
functionality of <CODE>gtk_table_new()</CODE> in our Tictactoe widget, we had
best avoid deriving it from Table. For that reason, we derive it
from VBox instead, and stick our table inside the VBox.
<P>
<H3>The header file</H3>

<P>Each widget class has a header file which declares the object and
class structures for that widget, along with public functions. 
A couple of features are worth pointing out. To prevent duplicate
definitions, we wrap the entire header file in:
<P>
<BLOCKQUOTE><CODE>
<PRE>
#ifndef __TICTACTOE_H__
#define __TICTACTOE_H__
.
.
.
#endif /* __TICTACTOE_H__ */
</PRE>
</CODE></BLOCKQUOTE>
<P>And to keep C++ programs that include the header file happy, in:
<P>
<BLOCKQUOTE><CODE>
<PRE>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
.
.
.
#ifdef __cplusplus
}
#endif /* __cplusplus */
</PRE>
</CODE></BLOCKQUOTE>
<P>Along with the functions and structures, we declare three standard
macros in our header file, <CODE>TICTACTOE(obj)</CODE>,
<CODE>TICTACTOE_CLASS(klass)</CODE>, and <CODE>IS_TICTACTOE(obj)</CODE>, which cast a
pointer into a pointer to the object or class structure, and check
if an object is a Tictactoe widget respectively.
<P>Here is the complete header file:
<P>
<BLOCKQUOTE><CODE>
<PRE>
/* tictactoe.h */

#ifndef __TICTACTOE_H__
#define __TICTACTOE_H__

#include &lt;gdk/gdk.h>
#include &lt;gtk/gtkvbox.h>

#ifdef __cplusplus
extern "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>
</CODE></BLOCKQUOTE>
<P>
<H3>The <CODE>_get_type()</CODE> function.</H3>

<P>We now continue on to the implementation of our widget. A core
function for every widget is the function
<CODE>WIDGETNAME_get_type()</CODE>. This function, when first called, tells
GTK about the widget class, and gets an ID that uniquely identifies
the widget class. Upon subsequent calls, it just returns the ID.
<P>
<BLOCKQUOTE><CODE>
<PRE>
guint
tictactoe_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 (), &amp;ttt_info);
    }

  return ttt_type;
}
</PRE>
</CODE></BLOCKQUOTE>
<P>The GtkTypeInfo structure has the following definition:
<P>
<BLOCKQUOTE><CODE>
<PRE>
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>
</CODE></BLOCKQUOTE>
<P>The fields of this structure are pretty self-explanatory. We'll ignore
the <CODE>arg_set_func</CODE> and <CODE>arg_get_func</CODE> fields here: they have an important, 
but as yet largely
unimplemented, role in allowing widget options to be conveniently set
from interpreted languages. Once GTK has a correctly filled in copy of
this structure, it knows how to create objects of a particular widget
type. 
<P>
<H3>The <CODE>_class_init()</CODE> function</H3>

<P>The <CODE>WIDGETNAME_class_init()</CODE> function initializes the fields of
the widget's class structure, and sets up any signals for the
class. For our Tictactoe widget it looks like:
<P>
<BLOCKQUOTE><CODE>
<PRE>

enum {
  TICTACTOE_SIGNAL,
  LAST_SIGNAL
};

static gint tictactoe_signals[LAST_SIGNAL] = { 0 };

static void
tictactoe_class_init (TictactoeClass *class)
{
  GtkObjectClass *object_class;

  object_class = (GtkObjectClass*) class;
  
  tictactoe_signals[TICTACTOE_SIGNAL] = gtk_signal_new ("tictactoe",
                                         GTK_RUN_FIRST,
                                         object_class->type,
                                         GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
                                         gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);


  gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);

  class->tictactoe = NULL;
}
</PRE>
</CODE></BLOCKQUOTE>
<P>Our widget has just one signal, the <CODE>tictactoe</CODE> signal that is
invoked when a row, column, or diagonal is completely filled in. Not
every composite widget needs signals, so if you are reading this for
the first time, you may want to skip to the next section now, as
things are going to get a bit complicated.
<P>The function:
<P>
<BLOCKQUOTE><CODE>
<PRE>
gint gtk_signal_new( const gchar         *name,
                     GtkSignalRunType     run_type,
                     GtkType              object_type,
                     gint                 function_offset,
                     GtkSignalMarshaller  marshaller,
                     GtkType              return_val,
                     guint                nparams,
                     ...);
</PRE>
</CODE></BLOCKQUOTE>
<P>Creates a new signal. The parameters are:
<P>
<UL>
<LI> <CODE>name</CODE>: The name of the signal.</LI>
<LI> <CODE>run_type</CODE>: Whether the default handler runs before or after
user handlers. Usually this will be <CODE>GTK_RUN_FIRST</CODE>, or <CODE>GTK_RUN_LAST</CODE>,
although there are other possibilities.</LI>
<LI> <CODE>object_type</CODE>: The ID of the object that this signal applies
to. (It will also apply to that objects descendants.)</LI>
<LI> <CODE>function_offset</CODE>: The offset within the class structure of
a pointer to the default handler.</LI>
<LI> <CODE>marshaller</CODE>: A function that is used to invoke the signal
handler. For signal handlers that have no arguments other than the
object that emitted the signal and user data, we can use the
pre-supplied marshaller function <CODE>gtk_signal_default_marshaller</CODE>.</LI>
<LI> <CODE>return_val</CODE>: The type of the return val.</LI>
<LI> <CODE>nparams</CODE>: The number of parameters of the signal handler
(other than the two default ones mentioned above)</LI>
<LI> <CODE>...</CODE>: The types of the parameters.</LI>
</UL>
<P>When specifying types, the <CODE>GtkType</CODE> enumeration is used:
<P>
<BLOCKQUOTE><CODE>
<PRE>
typedef enum
{
  GTK_TYPE_INVALID,
  GTK_TYPE_NONE,
  GTK_TYPE_CHAR,

?? 快捷鍵說明

復(fù)制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
亚洲女与黑人做爰| 91精品中文字幕一区二区三区| 国产精品无遮挡| 蜜桃一区二区三区在线| 精品日本一线二线三线不卡| 青青草原综合久久大伊人精品优势| 狠狠色狠狠色综合日日91app| 99久久伊人久久99| 亚洲视频在线一区| 一本高清dvd不卡在线观看| 18欧美亚洲精品| 欧美日韩国产bt| eeuss鲁片一区二区三区| 一区二区三区四区亚洲| 欧美丰满美乳xxx高潮www| 精品综合久久久久久8888| 欧美激情在线一区二区三区| 色综合久久久久网| 日本 国产 欧美色综合| 日本一区二区免费在线观看视频| 亚洲成人动漫在线免费观看| 欧美成人a在线| 不卡av电影在线播放| 日韩中文字幕麻豆| 欧美精品一区二区三区四区| 99热在这里有精品免费| 日韩在线一区二区三区| 亚洲国产精品av| 欧美精品777| 成人爱爱电影网址| 麻豆精品一区二区三区| 亚洲欧美在线另类| 精品少妇一区二区三区日产乱码 | 欧美日韩中文国产| 国产自产视频一区二区三区| 一区二区三区在线免费视频| 久久五月婷婷丁香社区| 欧美色电影在线| av中文字幕不卡| 久久99精品久久久| 波多野结衣亚洲| 免费一区二区视频| 亚洲一区在线观看视频| 久久一留热品黄| 欧美剧情片在线观看| 成人av在线播放网站| 精品一区二区三区免费播放| 一区二区三区精品在线观看| 久久久久久夜精品精品免费| 在线不卡的av| 在线亚洲免费视频| eeuss国产一区二区三区| 国产一区二区免费在线| 美日韩一级片在线观看| 亚洲第一久久影院| 一区二区视频免费在线观看| 欧美韩国日本不卡| 久久久久久久久久久黄色| 91精品国产高清一区二区三区| 日产欧产美韩系列久久99| 日韩理论片一区二区| 国产精品三级视频| 久久亚洲精华国产精华液| 91精品国产入口| 91麻豆高清视频| 99麻豆久久久国产精品免费优播| 18成人在线视频| 国产精品国产三级国产aⅴ无密码| 99精品视频在线免费观看| 精品夜夜嗨av一区二区三区| 日韩电影免费在线观看网站| 亚洲一区二区偷拍精品| 亚洲一区中文在线| 亚洲成人一区二区在线观看| 亚洲高清视频中文字幕| 亚洲与欧洲av电影| 亚洲午夜av在线| 午夜精品视频一区| 日韩高清在线不卡| 美女一区二区三区| 国内精品在线播放| 国产精品资源在线看| 懂色中文一区二区在线播放| 成人在线综合网| 99国产精品国产精品久久| 一本在线高清不卡dvd| 欧美中文一区二区三区| 欧美日韩一卡二卡| 欧美精品色一区二区三区| 91麻豆精品国产91| 久久久www免费人成精品| 国产精品无码永久免费888| 最新欧美精品一区二区三区| 亚洲永久免费av| 麻豆一区二区99久久久久| 国产福利不卡视频| 99久久精品国产麻豆演员表| 欧美亚一区二区| 日韩三级在线观看| 中文字幕高清不卡| 亚洲国产精品视频| 国产一区二区三区美女| 91亚洲精品久久久蜜桃| 欧美精品亚洲一区二区在线播放| 99九九99九九九视频精品| 欧美三级电影网| 精品少妇一区二区| 亚洲欧洲精品天堂一级| 亚洲女同女同女同女同女同69| 国产调教视频一区| 亚洲午夜一区二区| 国产一区免费电影| 色综合久久综合| 9191国产精品| 国产精品久久久久久妇女6080| 精品国产伦理网| 中文字幕一区二区三区色视频| 精品粉嫩aⅴ一区二区三区四区| 欧美色图在线观看| 久久嫩草精品久久久精品| 亚洲自拍与偷拍| 国产成人精品一区二区三区网站观看| 天涯成人国产亚洲精品一区av| 亚洲欧美另类久久久精品2019 | 欧美精品一区二区三区视频 | 亚洲高清免费在线| 国产精品性做久久久久久| 欧美性色欧美a在线播放| 精品99一区二区| 亚洲在线中文字幕| 懂色av中文字幕一区二区三区| 精品亚洲porn| 欧美主播一区二区三区| 国产夜色精品一区二区av| 日韩国产欧美在线视频| 国产成人av一区二区| 69堂成人精品免费视频| 亚洲精品欧美专区| 丁香五精品蜜臀久久久久99网站| 大美女一区二区三区| 欧美大片日本大片免费观看| 亚洲电影第三页| 91福利国产精品| 国产精品久久久久久久久久免费看| 国产精品欧美一区喷水| 久久aⅴ国产欧美74aaa| 欧美三级日韩三级| 中文字幕一区二区三区四区| 国产激情一区二区三区桃花岛亚洲| 国产馆精品极品| 欧美va亚洲va香蕉在线| 日韩精彩视频在线观看| 色综合久久六月婷婷中文字幕| 欧美日韩午夜影院| 亚洲六月丁香色婷婷综合久久 | 国产精品免费丝袜| 久久99精品国产.久久久久久| 国产成a人亚洲精| 久久久久久久综合| 激情久久五月天| 欧美videos大乳护士334| 蜜臀av性久久久久av蜜臀妖精| 极品少妇一区二区三区精品视频| 国产成人精品亚洲日本在线桃色| 91丨九色porny丨蝌蚪| 国产视频亚洲色图| 国产成人精品三级麻豆| 国产视频在线观看一区二区三区| 亚洲一区二区三区四区在线 | 欧美午夜影院一区| 亚洲综合999| 欧美日韩一级二级三级| 亚洲成a人v欧美综合天堂| 欧美羞羞免费网站| 亚洲bt欧美bt精品777| 欧美久久久久久久久| 美女脱光内衣内裤视频久久网站| 成人h动漫精品| 亚洲欧美自拍偷拍| 精品视频一区三区九区| 丝袜亚洲另类欧美| 精品久久久久久无| 国产在线看一区| 日本一区二区三区在线不卡| 成人国产在线观看| 亚洲永久免费视频| 日韩欧美的一区| 岛国一区二区三区| 一区二区三区视频在线观看| 欧美电影一区二区三区| 久久国内精品自在自线400部| 91福利社在线观看| 青青草国产精品亚洲专区无| 精品久久久久久久久久久院品网| 亚洲乱码日产精品bd| 在线综合视频播放| 国产成a人亚洲精品| 亚洲chinese男男1069| 久久精品亚洲国产奇米99| 在线观看网站黄不卡|