GTK<ip地址控件>

该控件共有三个文件myipaddress.c、myipaddress.h、test.c文件

**********************  myipaddress.h ******************************

#ifndef __MY_IP_ADDRESS_H__

#define __MY_IP_ADDRESS_H__

#include

#include

#include

G_BEGIN_DECLS

#define MY_IP_ADDRESS_TYPE          (my_ip_address_get_type ())

#define MY_IP_ADDRESS(obj)          (G_TYPE_CHECK_INSTANCE_CAST ((obj),  \

MY_IP_ADDRESS_TYPE, MyIPAddress))

#define MY_IP_ADDRESS_CLASS(klass)  (G_TYPE_CHECK_CLASS_CAST ((klass),  \

MY_IP_ADDRESS_TYPE, MyIPAddressClass))

#define IS_MY_IP_ADDRESS(obj)        (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \

MY_IP_ADDRESS_TYPE))

#define IS_MY_IP_ADDRESS_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), \

MY_IP_ADDRESS_TYPE))

typedef struct _MyIPAddress                MyIPAddress;

typedef struct _MyIPAddressClass            MyIPAddressClass;

struct _MyIPAddress

{

GtkEntry entry;

};

struct _MyIPAddressClass

{

GtkEntryClass parent_class;

void (* ip_changed) (MyIPAddress *ipaddress);

};

GType my_ip_address_get_type(void);

static void my_ip_address_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *pspec);

static void my_ip_address_class_init (MyIPAddressClass *klass);

static void my_ip_address_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *pspec);

static void my_ip_address_init (MyIPAddress *ipaddress);

static void my_ip_address_render(MyIPAddress *ipaddress);

static void my_ip_address_move_cursor(GObject *entry,GParamSpec *spec);

static gboolean my_ip_address_key_pressed(GtkEntry *entry,GdkEventKey *event);

GtkWidget *my_ip_address_new();

gchar *my_ip_address_get_address(MyIPAddress *ipaddress);

void my_ip_address_set_address(MyIPAddress *ipaddress,gint address[4]);

G_END_DECLS

#endif

**********************  myipaddress.c ******************************

#include

#include

#include

#include

#include "myipaddress.h"

#define MY_IP_ADDRESS_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj),MY_IP_ADDRESS_TYPE,MyIPAddressPrivate))

typedef struct _MyIPAddressPrivate

{

guint address[4];

};

enum

{

CHANGED_SIGNAL,

LAST_SIGNAL

};

enum

{

PROP_0,

PROP_IP1,

PROP_IP2,

PROP_IP3,

PROP_IP4

};

typedef struct _MyIPAddressPrivate MyIPAddressPrivate;

static guint my_ip_address_signals[LAST_SIGNAL] = {0};

GType my_ip_address_get_type(void)

{

static GType entry_type = 0;

if (!entry_type)

{

static const GTypeInfo entry_info =

{

sizeof (MyIPAddressClass),

NULL,

NULL,

(GClassInitFunc)my_ip_address_class_init,

NULL,

NULL,

sizeof(MyIPAddress),

0,

(GInstanceInitFunc)my_ip_address_init,

};

entry_type = g_type_register_static(GTK_TYPE_ENTRY, "MyIPAddress",&entry_info, 0);

}

return entry_type;

}

static void my_ip_address_set_property(GObject *object,guint prop_id,const GValue *value,GParamSpec *pspec)

{

MyIPAddress *ipaddress = MY_IP_ADDRESS(object);

gint address[4] = {-1, -1, -1, -1};

switch(prop_id)

{

case PROP_IP1:

address[0] = g_value_get_int(value);

my_ip_address_set_address(ipaddress,address);

break;

case PROP_IP2:

address[1] = g_value_get_int(value);

my_ip_address_set_address(ipaddress,address);

break;

case PROP_IP3:

address[2] = g_value_get_int(value);

my_ip_address_set_address(ipaddress,address);

break;

case PROP_IP4:

address[3] = g_value_get_int(value);

my_ip_address_set_address(ipaddress,address);

break;

default:

G_OBJECT_WARN_INVALID_PROPERTY_ID(object,prop_id,pspec);

break;

}

}

static void my_ip_address_class_init (MyIPAddressClass *klass)

{

GObjectClass *gobject_class = G_OBJECT_CLASS (klass);

gobject_class->set_property = my_ip_address_set_property;

gobject_class->get_property = my_ip_address_get_property;

g_type_class_add_private (klass, sizeof (MyIPAddressPrivate));

my_ip_address_signals[CHANGED_SIGNAL] =

g_signal_new ("ip-changed", G_TYPE_FROM_CLASS (klass),

G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,

G_STRUCT_OFFSET (MyIPAddressClass, ip_changed),

NULL, NULL,g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);

g_object_class_install_property (gobject_class, PROP_IP1,

g_param_spec_int ("ip-number-1",

"IP Address Number 1",

"The first IP address number",

0, 255, 0,

G_PARAM_READWRITE));

g_object_class_install_property (gobject_class, PROP_IP2,

g_param_spec_int ("ip-number-2",

"IP Address Number 2",

"The second IP address number",

0, 255, 0,

G_PARAM_READWRITE));

g_object_class_install_property (gobject_class, PROP_IP3,

g_param_spec_int ("ip-number-3",

"IP Address Number 3",

"The third IP address number",

0, 255, 0,

G_PARAM_READWRITE));

g_object_class_install_property (gobject_class, PROP_IP4,

g_param_spec_int ("ip-number-4",

"IP Address Number 1",

"The fourth IP address number",

0, 255, 0,

G_PARAM_READWRITE));

}

#define G_SIGNAL_OFFSET(struct_type,member)  ((glong)((guint8*) &((struct_type*)0)->member))

void (*callback)(gpointer instance,gpointer data);

void (*callback)(gpointer instance,gboolean arg,gpointer data);

static void my_ip_address_get_property(GObject *object,guint prop_id,GValue *value,GParamSpec *pspec)

{

MyIPAddress *ipaddress  = MY_IP_ADDRESS(object);

MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);

switch(prop_id)

{

case PROP_IP1:

g_value_set_int(value,priv->address[0]);

break;

case PROP_IP2:

g_value_set_int(value,priv->address[1]);

break;

case PROP_IP3:

g_value_set_int(value,priv->address[2]);

break;

case PROP_IP4:

g_value_set_int(value,priv->address[3]);

break;

default:

G_OBJECT_WARN_INVALID_PROPERTY_ID(object,prop_id,pspec);

break;

}

}

static void my_ip_address_init (MyIPAddress *ipaddress)

{

MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE (ipaddress);

PangoFontDescription *fd;

guint i;

for (i = 0; i < 4; i++)

priv->address[i] = 0;

fd = pango_font_description_from_string ("Monospace");

gtk_widget_modify_font (GTK_WIDGET (ipaddress), fd);

my_ip_address_render (ipaddress);

pango_font_description_free (fd);

g_signal_connect (G_OBJECT (ipaddress), "key-press-event",G_CALLBACK (my_ip_address_key_pressed), NULL);

g_signal_connect (G_OBJECT (ipaddress), "notify::cursor-position",G_CALLBACK (my_ip_address_move_cursor), NULL);

}

static void my_ip_address_render(MyIPAddress *ipaddress)

{

MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);

GString *text;

gint i;

text = g_string_new(NULL);

for(i=0; i<4; i++)

{

gchar *temp = g_strdup_printf("%3i.",priv->address[i]);

text = g_string_append(text,temp);

g_free(temp);

}

text = g_string_truncate(text,15);

gtk_entry_set_text(GTK_ENTRY(ipaddress),text->str);

g_string_free(text,TRUE);

}

static void my_ip_address_move_cursor(GObject *entry,GParamSpec *spec)

{

gint cursor = gtk_editable_get_position(GTK_EDITABLE(entry));

if(cursor <= 3)

{

gtk_editable_set_position(GTK_EDITABLE(entry),3);

}

else if(cursor <= 7)

{

gtk_editable_set_position(GTK_EDITABLE(entry),7);

}

else if(cursor <= 11)

{

gtk_editable_set_position(GTK_EDITABLE(entry),11);

}

else

gtk_editable_set_position(GTK_EDITABLE(entry),15);

}

static gboolean my_ip_address_key_pressed(GtkEntry *entry,GdkEventKey *event)

{

MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(entry);

guint k = event->keyval;

gint cursor,value;

if((k >= GDK_0 && k <= GDK_9) || (k >= GDK_KP_0 && k <= GDK_KP_9))

{

cursor = floor(gtk_editable_get_position(GTK_EDITABLE(entry))/4);

value = g_ascii_digit_value(event->string[0]);

if((priv->address[cursor] == 25) && (value > 5))

return TRUE;

if(priv->address[cursor] < 26)

{

priv->address[cursor] *= 10;

priv->address[cursor] += value;

my_ip_address_render(MY_IP_ADDRESS(entry));

gtk_editable_set_position(GTK_EDITABLE(entry),(4 * cursor) + 3);

g_signal_emit_by_name((gpointer)entry,"ip-changed");

}

}

else if(k == GDK_Tab)

{

cursor = (gint)(floor(gtk_editable_get_position(GTK_EDITABLE(entry))/4)+1);

gtk_editable_set_position(GTK_EDITABLE(entry),(4 * (cursor%4)) + 3);

}

else if(k == GDK_BackSpace)

{

cursor = (gint)floor(gtk_editable_get_position(GTK_EDITABLE(entry))/4);

priv->address[cursor] /= 10;

my_ip_address_render(MY_IP_ADDRESS(entry));

gtk_editable_set_position(GTK_EDITABLE(entry),(4*cursor)+3);

g_signal_emit_by_name((gpointer)entry,"ip-changed");

}

else if((k == GDK_Return) || (k == GDK_KP_Enter))

gtk_widget_activate(GTK_WIDGET(entry));

return TRUE;

}

GtkWidget *my_ip_address_new()

{

return GTK_WIDGET(g_object_new(my_ip_address_get_type(),NULL));

}

char *my_ip_address_get_address(MyIPAddress *ipaddress)

{

MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);

return g_strdup_printf("%d.%d.%d.%d",priv->address[0],priv->address[1],

priv->address[2],priv->address[3]);

}

void my_ip_address_set_address(MyIPAddress *ipaddress,gint address[4])

{

MyIPAddressPrivate *priv = MY_IP_ADDRESS_GET_PRIVATE(ipaddress);

guint i;

for(i=0; i<4; i++)

{

if(address[i] >= 0 && address[i] <= 255)

{

priv->address[i] = address[i];

}

}

my_ip_address_render(ipaddress);

g_signal_emit_by_name((gpointer)ipaddress,"ip-changed");

}

**********************  test.c ******************************

#include

#include "myipaddress.h"

static void ip_address_changed(MyIPAddress* ipaddress);

int main(int argc,char *argv[])

{

GtkWidget    *window,*ipaddress;

gtk_init(&argc,&argv);

gint address[4] = {0,0,0,0};

window=gtk_window_new(GTK_WINDOW_TOPLEVEL);

gtk_window_set_title(GTK_WINDOW(window),"MyIPAddress");

ipaddress = my_ip_address_new();

my_ip_address_set_address(MY_IP_ADDRESS(ipaddress),address);

g_signal_connect(G_OBJECT(ipaddress),"ip-changed",G_CALLBACK(ip_address_changed),NULL);

gtk_container_add(GTK_CONTAINER(window),ipaddress);

gtk_widget_show_all(window);

gtk_main();

return 0;

}

static void ip_address_changed(MyIPAddress* ipaddress)

{

gchar *address = my_ip_address_get_address(ipaddress);

g_print("%s\n",address);

g_free(address);

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,524评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,869评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,813评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,210评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,085评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,117评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,533评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,219评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,487评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,582评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,362评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,218评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,589评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,899评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,176评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,503评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,707评论 2 335

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,497评论 18 139
  • NAME dnsmasq - A lightweight DHCP and caching DNS server....
    ximitc阅读 2,773评论 0 0
  • 用了mysql好多年,很少关注mysql自带库,自然也不知道这个库里存放些什么,在看《MySQL排错指南》时看到它...
    灼灼2015阅读 1,836评论 1 3
  • 人以群分。缘分这东西,它就在那儿等着你,不早不晚。 我至今想不明白,是什么样的吸引力使我在刚刚完成川藏行、身心俱疲...
    飛閑雲阅读 743评论 5 4
  • 每一个做父母的都希望孩子受到最好的教育。陈淑红研究汉语教学的初衷也是如此。60年代出生的她,从小学习优异,老师同学...
    海外企业家阅读 2,290评论 1 2