当前位置:Linux教程 - Linux - GTK入门导读(Container物件)

GTK入门导读(Container物件)



         8. Container物件

    8.1 笔记本物件
    笔记本物件好几个\"页\"的集合, 它们互相交叠在一起, 并可包含不同的讯息. 这个物件在GUI越来越普及, 它是个在显示有类同功能的资讯时很有用的物件.

    第一个您会用到的是产生一个新的笔记本物件.


    GtkWidget* gtk_notebook_new (void);

    一旦物件产生後, 共有12个函数可以操作该笔记本物件. 我们一个一个来看.

    第一个是要如何来安排\"页标签\". 这些\"页标签\"或\"tabs\", 可以用四个位置, 上, 下, 左, 右.


    void gtk_notebook_set_tab_pos (GtkNotebook *notebook, GtkPositionType pos);

    GtkPostionType可以是以下四个, 很好认.

    GTK_POS_LEFT
    GTK_POS_RIGHT
    GTK_POS_TOP
    GTK_POS_BOTTOM
    GTK_POS_TOP是内定值.

    接下来我们来看如何加\"一页\"到笔记本上. 共有三种方法来加页到笔记本上.


    void gtk_notebook_append_page (GtkNotebook *notebook, GtkWidget *child, GtkWidget *tab_label);

    void gtk_notebook_prepend_page (GtkNotebook *notebook, GtkWidget *child, GtkWidget *tab_label);

    这些函数新增一页到笔记本, append由後新增, prepend由前新增. *child是要插入笔记本的物件, *tab_label是页标签.


    void gtk_notebook_insert_page (GtkNotebook *notebook, GtkWidget *child, GtkWidget *tab_label, gint position);

    参数与_append_及_prepend_相同, 除了多出一个参数, 位置. 该参数用来指定要插在那里.

    现在我们知道要如何新增一页, 再来看看如何移除.


    void gtk_notebook_remove_page (GtkNotebook *notebook, gint page_num);

    这个函数移除掉所指定的那一页.

    要找出目前正在那一页, 可用以下函数:


    gint gtk_notebook_current_page (GtkNotebook *notebook);

    以下两个函数是向前或向後移动. 若目前在最後一页, 而您用gtk_notebook_next_page, 那麽笔记本会绕回第一页, 反之亦然.


    void gtk_notebook_next_page (GtkNoteBook *notebook);
    void gtk_notebook_prev_page (GtkNoteBook *notebook);

    以下函数设定\"有效页\". 如果您希望笔记本开启到例如第五页, 您可以用这个函数. 内定页为第一页.


    void gtk_notebook_set_page (GtkNotebook *notebook, gint page_num);

    以下两个函数可新增及移除页标签及边框.


    void gtk_notebook_set_show_tabs (GtkNotebook *notebook, gint show_tabs);
    void gtk_notebook_set_show_border (GtkNotebook *notebook, gint show_border);

    show_tabs及show_border可以是TRUE或FALSE(0或1).

    现在我们来看个范例, 它是从testgtk.c中展开的, 用了所有13个函数. 该程式产生一个笔记本及六个按钮, 包含11页, 以三种方式加页, appended, inserted,及prepended. 这些按钮允许您旋转页标签位置, 新增/移除页标签及边框, 移除一页, 以前向及後向改变页的位置, 及离开程式.



    #include

    /* This function rotates the position of the tabs */
    void rotate_book (GtkButton *button, GtkNotebook *notebook)
    {
    gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos +1) %4);
    }

    /* Add/Remove the page tabs and the borders */
    void tabsborder_book (GtkButton *button, GtkNotebook *notebook)
    {
    gint tval = FALSE;
    gint bval = FALSE;
    if (notebook->show_tabs == 0)
    tval = TRUE;
    if (notebook->show_border == 0)
    bval = TRUE;

    gtk_notebook_set_show_tabs (notebook, tval);
    gtk_notebook_set_show_border (notebook, bval);
    }

    /* Remove a page from the notebook */
    void remove_book (GtkButton *button, GtkNotebook *notebook)
    {
    gint page;

    page = gtk_notebook_current_page(notebook);
    gtk_notebook_remove_page (notebook, page);
    /* Need to refresh the widget --
    This forces the widget to redraw itself. */
    gtk_widget_draw(GTK_WIDGET(notebook), NULL);
    }

    void destroy (GtkWidget *widget, gpointer *data)
    {
    gtk_main_quit ();
    }

    int main (int argc, char *argv[])
    {
    GtkWidget *window;
    GtkWidget *button;
    GtkWidget *table;
    GtkWidget *notebook;
    GtkWidget *frame;
    GtkWidget *label;
    GtkWidget *checkbutton;
    int i;
    char bufferf[32];
    char bufferl[32];

    gtk_init (&argc, &argv);

    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);

    gtk_signal_connect (GTK_OBJECT (window), \"destroy\",
    GTK_SIGNAL_FUNC (destroy), NULL);

    gtk_container_border_width (GTK_CONTAINER (window), 10);

    table = gtk_table_new(2,6,TRUE);
    gtk_container_add (GTK_CONTAINER (window), table);

    /* Create a new notebook, place the position of the tabs */
    notebook = gtk_notebook_new ();
    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
    gtk_table_attach_defaults(GTK_TABLE(table), notebook, 0,6,0,1);
    gtk_widget_show(notebook);

    /* lets append a bunch of pages to the notebook */
    for (i=0; i < 5; i++) {
    sprintf(bufferf, \"Append Frame %d\", i+1);
    sprintf(bufferl, \"Page %d\", i+1);

    frame = gtk_frame_new (bufferf);
    gtk_container_border_width (GTK_CONTAINER (frame), 10);
    gtk_widget_set_usize (frame, 100, 75);
    gtk_widget_show (frame);

    label = gtk_label_new (bufferf);
    gtk_container_add (GTK_CONTAINER (frame), label);
    gtk_widget_show (label);

    label = gtk_label_new (bufferl);
    gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
    }


    /* now lets add a page to a specific spot */
    checkbutton = gtk_check_button_new_with_label (\"Check me please!\");
    gtk_widget_set_usize(checkbutton, 100, 75);
    gtk_widget_show (checkbutton);

    label = gtk_label_new (\"Add spot\");
    gtk_container_add (GTK_CONTAINER (checkbutton), label);
    gtk_widget_show (label);
    label = gtk_label_new (\"Add page\");
    gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), checkbutton, label, 2);

    /* Now finally lets prepend pages to the notebook */
    for (i=0; i < 5; i++) {
    sprintf(bufferf, \"Prepend Frame %d\", i+1);
    sprintf(bufferl, \"PPage %d\", i+1);

    frame = gtk_frame_new (bufferf);
    gtk_container_border_width (GTK_CONTAINER (frame), 10);
    gtk_widget_set_usize (frame, 100, 75);
    gtk_widget_show (frame);

    label = gtk_label_new (bufferf);
    gtk_container_add (GTK_CONTAINER (frame), label);
    gtk_widget_show (label);

    label = gtk_label_new (bufferl);
    gtk_notebook_prepend_page (GTK_NOTEBOOK(notebook), frame, label);
    }

    /* Set what page to start at (page 4) */
    gtk_notebook_set_page (GTK_NOTEBOOK(notebook), 3);


    /* create a bunch of buttons */
    button = gtk_button_new_with_label (\"close\");
    gtk_signal_connect_object (GTK_OBJECT (button), \"clicked\",
    GTK_SIGNAL_FUNC (destroy), NULL);
    gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,1,2);
    gtk_widget_show(button);

    button = gtk_button_new_with_label (\"next page\");
    gtk_signal_connect_object (GTK_OBJECT (button), \"clicked\",
    (GtkSignalFunc) gtk_notebook_next_page,
    GTK_OBJECT (notebook));
    gtk_table_attach_defaults(GTK_TABLE(table), button, 1,2,1,2);
    gtk_widget_show(button);

    button = gtk_button_new_with_label (\"prev page\");
    gtk_signal_connect_object (GTK_OBJECT (button), \"clicked\",
    (GtkSignalFunc) gtk_notebook_prev_page,
    GTK_OBJECT (notebook));
    gtk_table_attach_defaults(GTK_TABLE(table), button, 2,3,1,2);
    gtk_widget_show(button);

    button = gtk_button_new_with_label (\"tab position\");
    gtk_signal_connect_object (GTK_OBJECT (button), \"clicked\",
    (GtkSignalFunc) rotate_book, GTK_OBJECT(notebook));
    gtk_table_attach_defaults(GTK_TABLE(table), button, 3,4,1,2);
    gtk_widget_show(button);

    button = gtk_button_new_with_label (\"tabs/border on/off\");
    gtk_signal_connect_object (GTK_OBJECT (button), \"clicked\",
    (GtkSignalFunc) tabsborder_book,
    GTK_OBJECT (notebook));
    gtk_table_attach_defaults(GTK_TABLE(table), button, 4,5,1,2);
    gtk_widget_show(button);

    button = gtk_button_new_with_label (\"remove page\");
    gtk_signal_connect_object (GTK_OBJECT (button), \"clicked\",
    (GtkSignalFunc) remove_book,
    GTK_OBJECT(notebook));
    gtk_table_attach_defaults(GTK_TABLE(table), button, 5,6,1,2);
    gtk_widget_show(button);

    gtk_widget_show(table);
    gtk_widget_show(window);

    gtk_main ();

    return 0;
    }



    8.2 卷动视窗
    卷动视窗是用来产生在视窗内可卷动的区域. 您可以在卷动视窗中插入任意种物件, 而不管视窗大小如何, 这些物件因为在卷动区域内, 因此都可以被用到.

    您可以用以下函数来产生卷动视窗:


    GtkWidget* gtk_scrolled_window_new (GtkAdjustment *hadjustment,
    GtkAdjustment *vadjustment);

    第一个参数是水平调整方向, 第二个是垂直调整方向. 它们一般被设为NULL.


    void gtk_scrolled_window_set_policy (GtkScrolledWindow *scrolled_window,
    GtkPolicyType hscrollbar_policy,
    GtkPolicyType vscrollbar_policy);

    第一个参数是想要改变的视窗. 第二个是设定水平卷动的方式, 第三个是垂直卷动的方式.

    policy可以是GTK_POLICY_AUTOMATIC, 或GTK_POLICY_ALWAYS. GTK_POLICY_AUTOMATIC会自动决定是否使用scrollbars. GTK_POLICY_ALWAYS则scrollbars始终在那里.

    这里是个将100个双态按钮包进一个卷动视窗的范例.


    #include

    void destroy(GtkWidget *widget, gpointer *data)
    {
    gtk_main_quit();
    }

    int main (int argc, char *argv[])
    {
    static GtkWidget *window;
    GtkWidget *scrolled_window;
    GtkWidget *table;
    GtkWidget *button;
    char buffer[32];
    int i, j;

    gtk_init (&argc, &argv);

    /* Create a new dialog window for the scrolled window to be
    * packed into. A dialog is just like a normal window except it has a
    * vbox and a horizontal seperator packed into it. It\"s just a shortcut
    * for creating dialogs */
    window = gtk_dialog_new ();
    gtk_signal_connect (GTK_OBJECT (window), \"destroy\",
    (GtkSignalFunc) destroy, NULL);
    gtk_window_set_title (GTK_WINDOW (window), \"dialog\");
    gtk_container_border_width (GTK_CONTAINER (window), 0);

    /* create a new scrolled window. */
    scrolled_window = gtk_scrolled_window_new (NULL, NULL);

    gtk_container_border_width (GTK_CONTAINER (scrolled_window), 10);

    /* the policy is one of GTK_POLICY AUTOMATIC, or GTK_POLICY_ALWAYS.
    * GTK_POLICY_AUTOMATIC will automatically decide whether you need
    * scrollbars, wheras GTK_POLICY_ALWAYS will always leave the scrollbars
    * there. The first one is the horizontal scrollbar, the second,
    * the vertical. */
    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
    /* The dialog window is created with a vbox packed into it. */
    gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window,
    TRUE, TRUE, 0);
    gtk_widget_show (scrolled_window);

    /* create a table of 10 by 10 squares. */
    table = gtk_table_new (10, 10, FALSE);

    /* set the spacing to 10 on x and 10 on y */
    gtk_table_set_row_spacings (GTK_TABLE (table), 10);
    gtk_table_set_col_spacings (GTK_TABLE (table), 10);

    /* pack the table into the scrolled window */
    gtk_container_add (GTK_CONTAINER (scrolled_window), table);
    gtk_widget_show (table);

    /* this simply creates a grid of toggle buttons on the table
    * to demonstrate the scrolled window. */
    for (i = 0; i < 10; i++)
    for (j = 0; j < 10; j++) {
    sprintf (buffer, \"button (%d,%d)\\n\", i, j);
    button = gtk_toggle_button_new_with_label (buffer);
    gtk_table_attach_defaults (GTK_TABLE (table), button,
    i, i+1, j, j+1);
    gtk_widget_show (button);
    }

    /* Add a \"close\" button to the bottom of the dialog */
    button = gtk_button_new_with_label (\"close\");
    gtk_signal_connect_object (GTK_OBJECT (button), \"clicked\",
    (GtkSignalFunc) gtk_widget_destroy,
    GTK_OBJECT (window));

    /* this makes it so the button is the default. */

    GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);

    /* This grabs this button to be the default button. Simply hitting
    * the \"Enter\" key will cause this button to activate. */
    gtk_widget_grab_default (button);
    gtk_widget_show (button);

    gtk_widget_show (window);

    gtk_main();

    return(0);
    }

    玩弄一下这个视窗. 您会看到scrollbars如何反应. 您也会想用用gtk_widget_set_usize()来设定视窗内定的大小.

    发布人:netbull 来自:Linux开发指南