Linux中国 Linux中国门户站!
设为主页 设为主页
收藏本站 收藏本站
 
当前位置 :首页 ->Linux技术 ->系统管理 ->正文

GTK入门导引

来源:Linux-cn.com 作者:Webmaster 时间:2007-05-05 点击: [收藏] [投稿]


The _class_init() function

  WIDGETNAME_class_init()函数启始设定该物件类别的资料, 并设定给该类别信号.


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_ARG_NONE, 0);
gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);
class->tictactoe = NULL;
}

  该函数只有一个信号, ``tictactoe''信号. 并非所有组合式物件都需要信号, 所以如果这是您第一次读这里, 您可以跳到下一个, 因为这里有点复杂.


gintgtk_signal_new (gchar*name,
GtkSignalRunType run_type,
gint object_type,
gint function_offset,
GtkSignalMarshallermarshaller,
GtkArgTypereturn_val,
gint nparams,
...);

  产生新讯号, 参数包含:

  name: 信号名称.

  run_type: 决定内定的处理器要在使用者的处理器之前处理或之後处理. 一般可以是GTK_RUN_FIRST, or GTK_RUN_LAST.

  object_type: 物件的ID.

  function_offset: 在类别结构中内定处理器函数位址值在记忆体中的偏移值.

  marshaller: 用来触发信号处理器的函数. 对除了使用者资料外, 没有额外参数的的信号处理器来说, 我们可以用内定的marshaller函数 gtk_signal_default_marshaller.

  return_val: 返回值的型态.

  nparams: 信号处理器的参数数量. (不同於以上所提的两个)

  ...: 参数型态.

  当指定型态时, 可用GtkArgType:


typedef enum
{
GTK_ARG_INVALID,
GTK_ARG_NONE,
GTK_ARG_CHAR,
GTK_ARG_SHORT,
GTK_ARG_INT,
GTK_ARG_LONG,
GTK_ARG_POINTER,
GTK_ARG_OBJECT,
GTK_ARG_FUNCTION,
GTK_ARG_SIGNAL
} GtkArgType;
The _init() function.
static void
tictactoe_init (Tictactoe *ttt)
{
GtkWidget *table;
gint i,j;
table = gtk_table_new (3, 3, TRUE);
gtk_container_add (GTK_CONTAINER(ttt), table);
gtk_widget_show (table);
for (i=0;i<3; i++)
for (j=0;j<3; j++)
{
ttt->buttons[i][j] = gtk_toggle_button_new ();
gtk_table_attach_defaults (GTK_TABLE(table), ttt->buttons[i][j], 
i, i+1, j, j+1);
gtk_signal_connect (GTK_OBJECT (ttt->buttons[i][j]), "toggled",
GTK_SIGNAL_FUNC (tictactoe_toggle), ttt);
gtk_widget_set_usize (ttt->buttons[i][j], 20, 20);
gtk_widget_show (ttt->buttons[i][j]);
}
}
GtkWidget*
tictactoe_new ()
{
return GTK_WIDGET ( gtk_type_new (tictactoe_get_type ()));
}
void
tictactoe_clear (Tictactoe *ttt)
{
int i,j;
for (i=0;i<3;i++)
for (j=0;j<3;j++)
{
gtk_signal_handler_block_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
gtk_toggle_button_set_state (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
 FALSE);
gtk_signal_handler_unblock_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
}
}
static void
tictactoe_toggle (GtkWidget *widget, Tictactoe *ttt)
{
int i,k;
static int rwins[8][3] = { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
 { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
 { 0, 1, 2 }, { 0, 1, 2 } };
static int cwins[8][3] = { { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
 { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
 { 0, 1, 2 }, { 2, 1, 0 } };
int success, found;
for (k=0; k<8; k++)
{
success = TRUE;
found = FALSE;
for (i=0;i<3;i++)
{
success = success && 
GTK_TOGGLE_BUTTON(ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
found = found ||
ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
}
if (success && found)
{
gtk_signal_emit (GTK_OBJECT (ttt), 
tictactoe_signals[TICTACTOE_SIGNAL]);
break;
}
}
}

  最後, 使用Tictactoe widget的范例程式:


#include <gtk/gtk.h>
#include "tictactoe.h"
/* Invoked when a row, column or diagonal is completed */
void
win (GtkWidget *widget, gpointer data)
{
g_print ("Yay!
");
tictactoe_clear (TICTACTOE (widget));
}
int 
main (int argc, char *argv[])
{
GtkWidget *window;
GtkWidget *ttt;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
gtk_signal_connect (GTK_OBJECT (window), "destroy",
GTK_SIGNAL_FUNC (gtk_exit), NULL);
gtk_container_border_width (GTK_CONTAINER (window), 10);
/* Create a new Tictactoe widget */
ttt = tictactoe_new ();
gtk_container_add (GTK_CONTAINER (window), ttt);
gtk_widget_show (ttt);
/* And attach to its "tictactoe" signal */
gtk_signal_connect (GTK_OBJECT (ttt), "tictactoe",
GTK_SIGNAL_FUNC (win), NULL);
gtk_widget_show (window);
gtk_main ();
return 0;
}


 如果您对本文有任何疑问或者建议,请到讨论区发表您的意见: >> 论坛入口 <<



上一篇:GTK+/Gnome应用开发   下一篇:GTK v1.2 Tutorial(英文)

文章评论】 【收藏本文】 【推荐好友】 【打印本文】 【我要投稿】 【论坛讨论
更多相关文章