<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<HTML
><HEAD
><TITLE
>从头创建构件</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
"><LINK
REL="HOME"
TITLE="GTK+ 2.0 教程"
HREF="book1.html"><LINK
REL="UP"
TITLE="编写你自己的构件"
HREF="c2132.html"><LINK
REL="PREVIOUS"
TITLE="创建一个复合构件"
HREF="x2152.html"><LINK
REL="NEXT"
TITLE="深入的学习"
HREF="x2367.html"></HEAD
><BODY
CLASS="SECT1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>GTK+ 2.0 教程</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="x2152.html"
ACCESSKEY="P"
><<< Previous</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>编写你自己的构件</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="x2367.html"
ACCESSKEY="N"
>Next >>></A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="SECT1"
><H1
CLASS="SECT1"
><A
NAME="SEC-CREATINGAWIDGETFROMSCRATCH">从头创建构件</H1
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN2261">介绍</H2
><P
>在这一节,我们将学习如何让构件把自己显示在屏幕上,以及如何让构件与事件交互。期间,我们将做一个表盘构件,用户可以拖动表盘上的指针来设定值。</P
><P
><SPAN
CLASS="INLINEMEDIAOBJECT"
><IMG
SRC="images/gtkdial.png"></SPAN
></P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN2268">在屏幕上显示构件</H2
><P
>在屏幕上显示需要几个相关步骤。在调用 <TT
CLASS="LITERAL"
>WIDGETNAME_new()</TT
> 创建构件之后,如下几个函数需要用到:</P
><P
></P
><UL
><LI
><P
> <TT
CLASS="LITERAL"
>WIDGETNAME_realize()</TT
> 如果构件有 X 窗口,该函数负责为构件创建 X 窗口。</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>WIDGETNAME_map()</TT
> 在用户调用 <TT
CLASS="LITERAL"
>gtk_widget_show()</TT
> 之后会调用该函数。它负责确保构件绘制在屏幕上。对于容器类,该函数必须调用每个子构件的 <TT
CLASS="LITERAL"
>map()</TT
> 函数。</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>WIDGETNAME_draw()</TT
> 当为构件或它的一个祖先调用 <TT
CLASS="LITERAL"
>gtk_widget_draw()</TT
> 时该函数被调用。它实际上是调用绘制函数在屏幕上绘制构件。对于容器构件,该函数必须为它的子构件调用 <TT
CLASS="LITERAL"
>gtk_widget_draw()</TT
>。</P
></LI
><LI
><P
> <TT
CLASS="LITERAL"
>WIDGETNAME_expose()</TT
> 是构件的暴露事件处理函数。它调用绘制函数把暴露的部分绘制在屏幕上。对于容器构件,该函数必须为无窗口子构件产生暴露事件。(如果它们有自己的窗口,X 会产生必需的暴露事件。)</P
></LI
></UL
><P
>你可能注意到后面的两个函数十分相似,都是负责在屏幕上绘制构件。实际上许多构件并不真正关心它们之间的不同。构件类里的默认 <TT
CLASS="LITERAL"
>draw()</TT
> 函数只是简单的为重绘区域产生一个暴露事件。然而,一些构件通过区分这两个函数可以减少操作。例如,如果一个构件有多个 X 窗口,因为暴露事件标识了暴露的窗口,它可以只重绘受影响的窗口,调用 <TT
CLASS="LITERAL"
>draw()</TT
> 是不可能这样的。</P
><P
>容器构件,即使它们自身并不关心这个差别,也不能简单的使用默认 <TT
CLASS="LITERAL"
>draw()</TT
> 函数,因为它的子构件可能需要注意这个差别。然而,在两个函数里重复绘制代码是一种浪费的。按惯例,构件有一个名为 <TT
CLASS="LITERAL"
>WIDGETNAME_paint()</TT
> 的函数做实际的绘制构件的工作,<TT
CLASS="LITERAL"
>draw()</TT
> 和 <TT
CLASS="LITERAL"
>expose()</TT
> 函数再调用它。</P
><P
>在我们的示例里,因为表盘构件不是一个容器构件,并且只有一个窗口,我们采用最简便的方法,用默认的 <TT
CLASS="LITERAL"
>draw()</TT
> 函数,并且仅仅实现一个 <TT
CLASS="LITERAL"
>expose()</TT
> 函数。</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN2300">表盘构件的原形</H2
><P
>正像陆上动物是从泥里爬出的两栖动物的变体,GTK 构件是其它的、以前写的构件的变体。因此,虽然这个章节命名为“从头创建构件”,但表盘构件实际上是从范围构件的源码上开始的。以它为起点是因为如果我们的表盘构件能与比例构件有相同的接口会好一些,比例构件是范围构件的继承。所以,虽然源代码在下面以完整的形式出现,它不能说是<I
CLASS="EMPHASIS"
>从头</I
>写出来的。如果你还不熟悉比例构件如何以应用程序作者的观点来运作,最好先看一下前面的章节。</P
></DIV
><DIV
CLASS="SECT2"
><H2
CLASS="SECT2"
><A
NAME="AEN2304">主体</H2
><P
>我们的构件中的相当多的一部分看起来与井字游戏构件十分相似。首先,我们有一个头文件:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
> /* GTK - GIMP工具包
* 版权 (C) 1995-1997 Peter Mattis, Spencer Kimball 和 Josh MacDonald 所有
*
* 本程序是自由软件。你可以在自由软件基金发布的 GNU GPL 的条款下重新分发
* 或修改它。GPL 可以使用版本 2 或(由你选择)任何随后的版本。
*
* 本程序分发的目的是它可能对其他人有用,但不提供任何的担保,包括隐含的
* 和适合特定用途的保证。请查阅GNU通用公共许可证获得详细的信息。
*
* 你应该已经随该软件一起收到一份GNU通用公共许可。如果还没有,请写信给
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#ifndef __GTK_DIAL_H__
#define __GTK_DIAL_H__
#include <gdk/gdk.h>
#include <gtk/gtkadjustment.h>
#include <gtk/gtkwidget.h>
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#define GTK_DIAL(obj) GTK_CHECK_CAST (obj, gtk_dial_get_type (), GtkDial)
#define GTK_DIAL_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, gtk_dial_get_type (), GtkDialClass)
#define GTK_IS_DIAL(obj) GTK_CHECK_TYPE (obj, gtk_dial_get_type ())
typedef struct _GtkDial GtkDial;
typedef struct _GtkDialClass GtkDialClass;
struct _GtkDial
{
GtkWidget widget;
/* 更新方式 (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
guint policy : 2;
/* 当前按下的按钮,如果没有该值是 0 */
guint8 button;
/* 表盘指针的大小 */
gint radius;
gint pointer_width;
/* 更新计时器的ID , 如果没有该值是 0 */
guint32 timer;
/* 当前角度 */
gfloat angle;
/* 将从调整对象中得到的旧值保存起来,这样在改变时我们就会知道 */
gfloat old_value;
gfloat old_lower;
gfloat old_upper;
/* 为这个表盘构件存储数据的调整对象 */
GtkAdjustment *adjustment;
};
struct _GtkDialClass
{
GtkWidgetClass parent_class;
};
GtkWidget* gtk_dial_new (GtkAdjustment *adjustment);
GtkType gtk_dial_get_type (void);
GtkAdjustment* gtk_dial_get_adjustment (GtkDial *dial);
void gtk_dial_set_update_policy (GtkDial *dial,
GtkUpdateType policy);
void gtk_dial_set_adjustment (GtkDial *dial,
GtkAdjustment *adjustment);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_DIAL_H__ */</PRE
></TD
></TR
></TABLE
><P
>因为相对于上一个构件,这个构件我们要做的工作更多,所以在数据结构里有更多的域,但是其它地方一样。</P
><P
>接下来,在包含了头文件和声明了几个常量之后,我们有几个提供构件信息的函数和初始化构件的函数:</P
><TABLE
BORDER="0"
BGCOLOR="#E0E0E0"
WIDTH="100%"
><TR
><TD
><PRE
CLASS="PROGRAMLISTING"
>#include <math.h>
#include <stdio.h>
#include <gtk/gtkmain.h>
#include <gtk/gtksignal.h>
#include "gtkdial.h"
#define SCROLL_DELAY_LENGTH 300
#define DIAL_DEFAULT_SIZE 100
/* 声明 */
[ 省略以节省空间 ]
/* 局部数据 */
static GtkWidgetClass *parent_class = NULL;
GtkType
gtk_dial_get_type ()
{
static GtkType dial_type = 0;
if (!dial_type)
{
static const GtkTypeInfo dial_info =
{
"GtkDial",
sizeof (GtkDial),
sizeof (GtkDialClass),
(GtkClassInitFunc) gtk_dial_class_init,
(GtkObjectInitFunc) gtk_dial_init,
/* reserved_1 */ NULL,
/* reserved_1 */ NULL,
(GtkClassInitFunc) NULL
};
dial_type = gtk_type_unique (GTK_TYPE_WIDGET, &dial_info);
}
return dial_type;
}
static void
gtk_dial_class_init (GtkDialClass *class)
{
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
parent_class = gtk_type_class (gtk_widget_get_type ());
object_class->destroy = gtk_dial_destroy;
widget_class->realize = gtk_dial_realize;
widget_class->expose_event = gtk_dial_expose;
widget_class->siz
没有合适的资源?快使用搜索试试~ 我知道了~
gtk2教程(网页版)
共178个文件
html:135个
png:31个
gif:12个
需积分: 10 3 下载量 199 浏览量
2008-12-28
11:06:56
上传
评论
收藏 489KB RAR 举报
温馨提示
有关通过 C 语言接口使用 GTK (the GIMP Toolkit) 的教程。
资源推荐
资源详情
资源评论
收起资源包目录
gtk2教程(网页版) (178个子文件)
important.gif 1KB
note.gif 1KB
warning.gif 1KB
caution.gif 1KB
tip.gif 1KB
home.gif 995B
next.gif 964B
prev.gif 944B
up.gif 922B
toc-plus.gif 846B
toc-minus.gif 843B
toc-blank.gif 95B
x2259.html 26KB
x2859.html 23KB
c2878.html 21KB
x1163.html 19KB
x1465.html 17KB
x1030.html 17KB
x2152.html 15KB
x2870.html 14KB
book1.html 13KB
x1513.html 13KB
x806.html 12KB
x2473.html 12KB
x892.html 11KB
x450.html 11KB
a2711.html 10KB
x2648.html 10KB
c1562.html 9KB
c816.html 9KB
x344.html 9KB
a2845.html 9KB
x1247.html 9KB
x2418.html 8KB
c103.html 8KB
x1002.html 8KB
x2379.html 8KB
x1398.html 8KB
x1827.html 8KB
x954.html 8KB
x607.html 8KB
x1126.html 8KB
x1431.html 7KB
x453.html 7KB
x1893.html 7KB
x1804.html 6KB
x982.html 6KB
x245.html 6KB
x1453.html 6KB
x1639.html 6KB
x1651.html 6KB
x708.html 5KB
c554.html 5KB
x666.html 5KB
x1321.html 5KB
c69.html 5KB
x856.html 5KB
x1380.html 5KB
x1354.html 5KB
x223.html 5KB
x2129.html 5KB
x408.html 5KB
x1270.html 5KB
c1289.html 5KB
x2088.html 5KB
x747.html 5KB
x1989.html 5KB
x505.html 5KB
c2570.html 5KB
c1751.html 5KB
x924.html 4KB
c628.html 4KB
x583.html 4KB
c17.html 4KB
x2034.html 4KB
x427.html 4KB
x873.html 4KB
x2047.html 4KB
c514.html 4KB
x2660.html 4KB
x542.html 4KB
x1342.html 4KB
c2068.html 4KB
x175.html 4KB
x1415.html 4KB
c1977.html 4KB
x398.html 3KB
x2014.html 3KB
c696.html 3KB
x2141.html 3KB
x652.html 3KB
x1724.html 3KB
x1306.html 3KB
c418.html 3KB
x1764.html 3KB
c1788.html 3KB
x1875.html 3KB
c1853.html 3KB
x788.html 3KB
x2010.html 3KB
共 178 条
- 1
- 2
资源评论
dong_miao
- 粉丝: 2
- 资源: 6
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功