Previous Next Contents

6. 按钮物件

6.1 一般按钮

我们到现在为止一直都看到按钮物件. 实在很简单. 有两种方法来产生按钮, 您可以用gtk_button_new_with_label() 来产生一个有标签的按钮, 或用gtk_button_new()来产生一个空按钮. 现在您可以任意操作它, 接张图(pixmap)或标签上去, 随你. 要达到这样的效果, 先产生一个box, 然後用gtk_box_pack_start 将您的objects封装进这个box. 然後用gtk_container_add来封装这个box到按钮中.

这里是个使用gtk_button_new来产生一张有图片及标签的按钮. 我将程式分细使您在往後可以利用这个程式.

#include <gtk/gtk.h>


/* create a new hbox with an image and a label packed into it
 * and return the box.. */

GtkWidget *xpm_label_box (GtkWidget *parent, gchar *xpm_filename, gchar *label_text)
{
    GtkWidget *box1;
    GtkWidget *label;
    GtkWidget *pixmapwid;
    GdkPixmap *pixmap;
    GdkBitmap *mask;
    GtkStyle *style;

    /* create box for xpm and label */
    box1 = gtk_hbox_new (FALSE, 0);
    gtk_container_border_width (GTK_CONTAINER (box1), 2);

    /* get style of button.. I assume it's to get the background color.
     * if someone knows the real reason, please enlighten me. */
    style = gtk_widget_get_style(parent);

    /* now on to the xpm stuff.. load xpm */
    pixmap = gdk_pixmap_create_from_xpm (parent->window, &mask,
                                         &style->bg[GTK_STATE_NORMAL],
                                         xpm_filename);
    pixmapwid = gtk_pixmap_new (pixmap, mask);

    /* create label for button */
    label = gtk_label_new (label_text);

    /* pack the pixmap and label into the box */
    gtk_box_pack_start (GTK_BOX (box1),
                        pixmapwid, FALSE, FALSE, 3);

    gtk_box_pack_start (GTK_BOX (box1), label, FALSE, FALSE, 3);

    gtk_widget_show(pixmapwid);
    gtk_widget_show(label);

    return (box1);
}

/* our usual callback function */
void callback (GtkWidget *widget, gpointer *data)
{
    g_print ("Hello again - %s was pressed\n", (char *) data);
}


int main (int argc, char *argv[])
{
    /* GtkWidget is the storage type for widgets */
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *box1;

    gtk_init (&argc, &argv);

    /* create a new window */
    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    gtk_window_set_title (GTK_WINDOW (window), "Pixmap'd Buttons!");

    /* It's a good idea to do this for all windows. */
    gtk_signal_connect (GTK_OBJECT (window), "destroy",
                        GTK_SIGNAL_FUNC (gtk_exit), NULL);


    /* sets the border width of the window. */
    gtk_container_border_width (GTK_CONTAINER (window), 10);

    /* create a new button */
    button = gtk_button_new ();

    /* You should be getting used to seeing most of these functions by now */
    gtk_signal_connect (GTK_OBJECT (button), "clicked",
                        GTK_SIGNAL_FUNC (callback), (gpointer) "cool button");

    /* this calls our box creating function */
    box1 = xpm_label_box(window, "info.xpm", "cool button");

    /* pack and show all our widgets */
    gtk_widget_show(box1);

    gtk_container_add (GTK_CONTAINER (button), box1);

    gtk_widget_show(button);

    gtk_container_add (GTK_CONTAINER (window), button);

    gtk_widget_show (window);

    /* rest in gtk_main and wait for the fun to begin! */
    gtk_main ();

    return 0;
}

xpm_label_box函数可用来包装xpm及labels到物件中使其成为container.

6.2 双态按钮

双态按钮跟一般按钮很像, 除了它们有两种状态, 由"click"来切换. 他们可以是"被按下的", 当您再按一次, 它们会还原. 再按一次会再被按下去.

双态按钮是check按钮及radio按钮的基础. 它们有许多函数是继承双态按钮而来. 我等一下会把它们指出来.

产生一个双态按钮:

GtkWidget* gtk_toggle_button_new (void);

GtkWidget* gtk_toggle_button_new_with_label (gchar *label);

您可以看到, 这些跟一般按钮函数的用法一模一样. 第一个产生一个空白的双态按钮, 第二个则有个标签包在一起.

要取得双态按钮的状态, 包含了check及radio按钮也一样, 我们用以下范例中所使用的巨集. 这会测试该按钮的状态. 当我们按下按钮时, 双态按钮的信号("toggled")会送给我们. 要取得其状态, 设定好信号处理器来接取"toggled"信号, 并使用该巨集来决定其状态. 该callback函数看起来像这样:

void toggle_button_callback (GtkWidget *widget, gpointer   data)
{
    if (GTK_TOGGLE_BUTTON (widget)->active) 
    {
        /* If control reaches here, the toggle button is depressed. */
    }
}

void gtk_toggle_button_set_state (GtkToggleButton *toggle_button,
                                  gint state);

以上的函数呼叫可用来设定双态按钮的状态(包含check及radio) 传您所产生的按钮做为第一个参数, 然後TRUE或FALSE做为第二个用来指定它是up(release)或down(depressed). 内定值是up, 或FALSE.

void       gtk_toggle_button_toggled        (GtkToggleButton *toggle_button);

这个会切换该按钮, 并送出"toggled"信号.

6.3 Check按钮

Check按钮有很多性质与双态按钮一样, 但外观看起来不同. 在文字上没有边框, 而在左边有个小方块. 这个在软体中选择要不要某个选项用得很频繁.

两个产生的函数跟一般按钮一样.

GtkWidget* gtk_check_button_new (void);

GtkWidget* gtk_check_button_new_with_label (gchar *label);

new_with_label函数产生一个check按钮并带一个标签在其右侧.

测试check按钮的方法跟双态按钮一样.

6.4 Radio Buttons

Radio按钮与check按钮很像, 除了它们是成群的. 因而我们可以 在一群中选择其中一个.

产生一个新的radio按钮是由以下函数所达成的:

GtkWidget* gtk_radio_button_new (GSList *group);

GtkWidget* gtk_radio_button_new_with_label (GSList *group,
                                            gchar *label);

您看到有个额外的参数. 因为它需要一个group来达成这项工作. 第一个函数可以用NULL来做参数. 然後产生一个group:

GSList* gtk_radio_button_group (GtkRadioButton *radio_button);

然後传这个group做为第一个参数给gtk_radio_button_new或new_with_label. 您也可以乾脆指明那一个是内定的.

void gtk_toggle_button_set_state (GtkToggleButton *toggle_button,
                                  gint state);

这个跟双态按钮一样.


Previous Next Contents