Linux 版 (精华区)

发信人: netiscpu (平淡是真), 信区: Linux
标  题: GTK入门导引(8)
发信站: 紫 丁 香 (Mon Dec 14 14:42:17 1998), 转信


发信人: hey (吟风·悠游98), 信区: Unix
标  题: GTK入门导引(8)
发信站: 华南网木棉站 (Tue Nov 10 10:55:33 1998), 转信

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 <gtk/gtk.h>

    /* 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 <gtk/gtk.h>

    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()来设定视窗内定的大小. 

--
        6m3m┌───────────────────────┐0m
        6m3m│     4m疾如风,徐如林,侵掠如火,不动如山       3m│4m 0m
        6m3m└───────────────────────┘0m4m 0m
          4m                                                 0m

m;32m※ 来源:.华南网木棉站 bbs.gznet.edu.cn.[FROM: 202.38.212.66]m
--
m;32m※ 转寄:.华南网木棉站 bbs.gznet.edu.cn.[FROM: mtlab.hit.edu.cn]
--

                              Enjoy Linux!
                          -----It's FREE!-----

※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: mtlab.hit.edu.cn]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:213.700毫秒