GTK

作者: 康大虎 | 来源:发表于2016-07-06 12:28 被阅读0次

    该控件共有三个文件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);

    }

    相关文章

      网友评论

          本文标题:GTK

          本文链接:https://www.haomeiwen.com/subject/bgjkjttx.html