控件的介紹

一.控件的介紹

在上一篇中,我們講述過 Gtk2-perl 的內部控件,並將大的分類簡單介紹了一下。在這裏,我們會詳細的說明一下某些控件,讓大家能較爲清楚的瞭解這些控件。注意,每個控件內部都有很多的調用函數,如果要講解每個控件的所有函數將要耗費大量的篇章,所以這裏只是講解一些基本的或者重要的函數。

我們先來講一下這些控件的用途:

Gtk2-perl 中的控件有很多,但是無外乎這幾種類型,一種是用來顯示數據的,一種用來操作數據的,一種是用來將其他控件佈局的,還有一種是特殊目的的控件。

1、顯示數據的控件一般可以顯示文字數據,圖片數據或者其他特殊數據。這類控件的特點是主要用來顯示數據,顯示的數據一般是不可編輯或操作的。用戶一般可以通過這類控件得到某些信息,但是不能操作這些控件。更具體的:

顯示文字數據的控件我們一般使用 Gtk2::Label,這個控件主要是用來顯示一小段文字從而表現一個標題或者一點提示的作用,也就是說是用來點綴程序的。

顯示圖片數據的控件我們一般是用Gtk2::Image,這個控件的目的就是用來顯示一個圖片,與上面的 Gtk2::Label 的作用基本相似。

我們還有顯示進度條的控件Gtk2::ProgressBar,這個控件可以顯示一個進度條,來指示用戶當前某個程序的進展情況,在某些長時間運行的程序中我們經常可以見到。

Gtk2::Statusbar 顯示一個狀態欄。這個控件一般用在程序的底部,顯示某些提示信息給用戶。

Gtk2::Frame 一個裝飾性的控件,顯示一個外邊框並帶有一個標題。它的內部可以再嵌入一個子控件。

Gtk2::Hseparator 另一個裝飾性的控件,顯示一個一條水平分割線。

Gtk2::Vseparator 同上,顯示一個垂直分割線。

Gtk2::List 一個列表形的控件。就是將數據以垂直排列的方式顯示出來。經常用來羅列很多相似的數據。可以按照數據的值來排序顯示。

Gtk2::TreeView 樹形顯示控件。主要用來以樹形方式顯示數據。例如:類似我們經常使用的win32下的資源管理器就是一個典型的樹形控件的例子。在這個控件中你可以顯示一個樹形列表,可以展開或者收縮這個列表,可以編輯這個列表中的每一項,可以在這個列表中使用簡單的按鈕等等。這個控件通常與Gtk2::TreeStore 等其他控件一同使用。這個控件的概念也與操作類型的控件有些重複,它不僅顯示,還可以讓用戶操作。

2、操作數據的控件一般可以讓用戶來輸入或編輯文字,或者選擇某個選項,或者觸發某個事件,例如:點擊按鈕來運行某個函數。

Gtk2::Button 一個普通的按鈕控件,當點擊時我們可以觸發某個事件。

Gtk2::CheckButton 一個check(打對勾)類型的按鈕,一般有兩種狀態:選擇或者沒有選擇。

Gtk2::RadioButton 一個radio(小圓點)類型的按鈕,一般是多個radio類型的按鈕,然後我們在其中選擇一個,經常用於互斥選擇。

Gtk2::ToggleButton 一個toggle(和開關類似)類型的按鈕,按下後會保持按下的狀態直到用戶再次按下才顯示按鈕鬆開。

Gtk2::Entry 一個單行文字的輸入框。用戶可以在這裏輸入一行文字

Gtk2::TextView 強大的文字控件,不僅可以讓用戶輸入、顯示、編輯多行文字,而且可以顯示靜態圖片或者簡單的動畫圖片,甚至可以嵌入其他的控件,例如,嵌入按鈕控件等等。這個控件的使用在後面我們會詳細的講述。

Gtk2::Combo 一個選擇控件。很像html中的select下拉菜單,點擊後出現一個下拉菜單,用戶可以在下拉菜單的多個選項中選擇一個選項。一般常用在工具欄中,例如:word中我們可以在工具欄裏直接選擇一個字體,或者字體的大小時,我們都會用到該類型的控件。

Gtk2::SpinButton 一個數字選擇控件。這個控件主要用來在一定的範圍內選擇一個數字,控件的左邊是上下選擇的兩個按鈕,可以讓用戶將所選擇的數字加1或減1,用戶也可以直接在控件中輸入自己需要的數字。

Gtk2::Hscale 和 Gtk2::Vscale 水平和豎直輸入框。這個框水平或者豎直顯示一個移動條,用戶移動這個條就可以在一定的範圍內選擇一箇中間值來作爲輸入的數據,不太常見。

3、將其他控件佈局的控件一般並不明確的顯示在用戶的面前,它們只是負責將其他的控件在主窗口中擺放整齊。在這裏一般有兩種佈局的思想,一種是使用 table 的方式將主窗口橫豎的劃分,然後將所需的控件按照自己的要求放入劃分出來的每個單元中;另一種是使用畫布式的方式,你可以隨意的擺放所有的控件,只要你準確的說出每個控件在主窗口中的座標就可以。

按照table方式佈局的控件有:

Gtk2::HBox 一個用來水平分割的控件,目的是在不同水平上擺放多個控件。

Gtk2::VBox 一個豎直分割的控件。目的類上。

Gtk2::Table 一個按照表格的方式來分割的控件,也就是同時既有水平分割也有豎直分割,是上面兩個控件的結合體。

按照畫布方式佈局的控件有:

Gtk2::Fixed 這個控件可以讓你在它內部的任意位置放置固定的子控件。不過,這個控件有些缺點:例如可能會導致文字的被截斷,或者多個子控件的重疊等顯示問題。所以這裏並不太推薦使用該控件。

Gtk2::Layout這個控件可以讓你在它內部自由放置子控件,但是它支持滾動窗口,可以有無限的滾動區域。這個控件是爲了彌補Gtk2::Fixed中的缺陷而編寫的,它與Gtk2::Fixed的用法基本相同,因此推薦使用這個。

爲了達到某些複雜佈局的目的,很多時候佈局控件都是混合使用的。不過,總的來說,按照table方式佈局更加容易。

4、特殊目的的控件在Gtk2-perl中有很多,它們都有自己特殊的目的,而我也將大多數無法以上面的形式分類的控件都歸結到這裏了。

  • 首先這樣一類控件是選擇類控件,這類控件的目的是跳出一個新窗口,來完成某個在很多程序中都通用的功能。

    Gtk2::ColorSelection 顏色選擇控件。跳出一個通用的顏色選擇窗口,用戶可以按照紅、綠、藍的方式來選擇一個自己要求的顏色,用戶還可以調節顏色的不透明度、飽和值、色調,然後返回用戶所選擇的顏色值。

    Gtk2::ColorSelection圖例:



    Gtk2::FontSelection 字體選擇控件。跳出一個通用的字體選擇窗口(該窗口中可以選擇的字體都是讀取的當前系統所擁有的字體),用戶可以選擇字體,字體大小以及樣式,並伴有當前選擇字體的一個預覽。

    Gtk2::FontSelection圖例:



    Gtk2::FileSelection 文件選擇控件。跳出一個文件選擇窗口,可以讓用戶單選或多選文件,還可以選擇目錄、建立文件或建立目錄。用戶可以自由的更換目錄,不過這個文件選擇框與windows平臺的文件選擇框的樣式不同,應該說它們都有各自的優勢吧。

    Gtk2::FileSelection圖例:



    Gtk2::Calendar 日曆控件。顯示一個標準的公曆日曆,用戶可以查看當前的年、月、日,或者選擇一個當前的日期。

    Gtk2::Dialog 一個簡單的對話框,上面可以有幾個簡單的按鈕選擇,例如:確定、取消、應用。這個控件一般用來處理某些用戶的簡單選擇,例如:提示用戶程序出錯,提示用戶是否存儲文件等等。

  • 其次,菜單類的控件。這類控件都是用來在程序的頂部顯示一個通常意義上的菜單或者工具欄。

    Gtk2::Menu 一個標準的菜單控件。這個控件可以讓我們產生下拉菜單並在這個下拉菜單中包含多個菜單選項或者更深的級聯菜單。每個菜單項可以對應於一個觸發事件。菜單上可以添加圖標,還可以添加快捷鍵。

    Gtk2::Toolbar 標準的工具欄控件。我們都清楚,現在的GUI程序一般在菜單下面會有一個快捷工具欄,這個工具欄內放入一些特別常用的按鈕,來方便用戶的迅速使用。Gtk2::Toolbar 就是這樣的標準工具欄。它允許插入文字、圖標按鈕。

  • 再次,還有一些控件的目的就更加特殊了。

    Gtk2::Scrollbar 滾動窗口控件。這個控件相當的重要,很多時候如果我們要顯示的內容在程序的主窗口中無法完全顯示,我們就需要加入這個控件,更準確的說是將顯示數據的控件加入到 Gtk2::Scrollbar 控件中,這樣我們就可以有水平與垂直的滾動條來滾動顯示多出窗口的數據。

    Gtk2::DrawingArea 相當重要的控件,可以稱之爲繪圖控件。這個控件可以幫助我們建立自己的控件或者是不使用任何現有的控件直接調用底層的繪圖指令。我們都很清楚,現有的控件也許可以建立標準的一個GUI程序,但是我們在寫GUI程序的時候,很有可能有自己的特殊需求,需要的控件並不能在標準控件中找到,這時我們就需要用Gtk2::DrawingArea。要使用該控件就必須瞭解Glib、pango等模塊。在下一篇中我們將講解這個控件的使用。

    Gtk2::Tooltips 提示控件。這個控件專門用來對於GUI界面上的一些簡單標籤做更詳細的解釋,例如:當我們將鼠標停放在界面的某個標籤上時,過一會可以出現一個文字框來對於這個標籤做更詳細解釋。

    Gtk2::Notebook 紀事本控件。這個控件也是相當強大,就像我們在firefox裏最常使用的tab窗口一樣,我們可以通過這個控件來在一個主窗口中嵌入多個控件,而每個控件通過控件上方的標籤來切換顯示。微軟在IE7中也採用了類似的控件。

基本上,上述的控件就是我認爲在 Gtk2-perl 編程中經常要使用到的,還有一些較爲偏僻的控件,在這裏就暫不介紹了。下面,我們來針對幾個較爲重要的控件詳細的說明一下。


二.Gtk2::Window

這個可以說是最重要的控件了, Gtk2::Window 決定了你所顯示的主窗口的樣式以及相應的一系列設置。

我們這裏通過代碼來說明:


my $win = Gtk2::Window -> new ( $type ) ; ## 建立一個新的窗口對象
$win -> set_title ( "Test for window" ) ; ## 設置這個窗口的標題
$win -> set_default_icon_from_file ( $filename ); ## 設置窗口的小圖標
$win->set_size_request ( "800" , "600" ) ; ## 設置這個窗口的大小
$win -> set_position ( 'center' ) ; ## 設置這個窗口的位置
$win -> set_type_hint ( $hint ); ## 設置這個窗口暗示類型
$win -> signal_connect ( 'destroy' , sub { Gtk2->main_quit } ) ; ## 設置窗口退出時程序退出

 

一個新窗口的圖例:



 

第一行裏面的 $type 值可以爲:toplevel 或 popup。 toplevel 代表了這個窗口是最頂層的窗口,這個窗口可以包含其他的窗口,是我們最常用的窗口類型;popup代表這個窗口只是彈出窗口,這個窗口一般是菜單窗口或者工具提示窗口,通常就是一個彈出式的提示窗口。缺省的話就是toplevel。

第二行,我們可以設置窗口的標題,注意這裏的標題文字必須是 utf8 編碼,所以當你輸入中文時一般需要轉換編碼。我們可以用$win -> get_title 來取回當前窗口的標題,例如:當我們想要在當前窗口標題的基礎上添加某些文字時就常用這個。

第三行,我們設置了一個圖標,這個圖標是直接從硬盤上的文件取出,文件的格式可以爲 png、jpg、gif、bmp,圖標的大小一般爲16x16像素,如果太大則只會裁去16x16範圍以外的部分。

第四行,我們設置了窗口大小,我們還可以固定窗口的大小:$win -> set_resizable ( 0 );或者隨時改變窗口的大小:$win -> resize ( $width , $height ); 或者取回當前窗口大小:( $w,$h ) = $win -> get_size。當然,我們還可以將窗口全屏顯示:$win -> fullscreen; 或者取消全屏:$win -> unfullscreen; 最大化也是如此:$win -> maximize; $win -> unmaximize; 。

第五行,我們設置的是窗口剛被創建時所出現的位置。這裏可以有:none、center、center-always、center-on-parent、mouse。None的話代表隨機出現,mouse的話代表窗口的右上角出現在鼠標指針的位置上。

第六行,我們設置窗口的暗示類型。可以設置的值有:normal、dialog、menu、toolbar、splashscreen、utility、dock、desktop。

Splashscreen可以稱之爲閃屏,就是我們在啓動程序時常見的一個顯示窗口,隨着程序的啓動完成這個窗口也會隨之消失而變爲正式的程序操作窗口,這樣的窗口在現代GUI程序中十分常見,主要是爲了在用戶等待程序的全部讀入時給用戶一個較好的印象。這個Splashscreen 窗口沒有最大最小化、關閉的按鈕。

Desktop稱爲桌面。也就是說這個窗口會作爲一個桌面出現,並沒有任何的標題或者最大最小化、關閉等按鈕。在這裏,必須強調一點:win32與X11的不同。例如:在win32環境下Desktop 暗示就無法起作用,它只能作用在X11環境中。所以當你試圖編寫一個跨平臺運行的程序時,就要避免使用這種選項。

dock 船塢選項。這個選項是使窗口作爲一個小面板來出現的。該選項同樣只能在X11環境中使用。具體的使用可以參考x11的內部協議規定。

注意:在win32下很多暗示選項是不起作用的。

這裏還要介紹一個函數:$win -> set_decorated,它的作用是將窗口的裝飾去掉,也就是去掉窗口的標題、最大化最小化關閉按鈕所在的那一行,窗口作爲一個裸窗口顯示。當我們需要在win32下使用這種窗口時,可以先設置一個特殊的窗口暗示類型,然後再$win -> set_decorated (0); 就可以。

也許大家都會有疑問,我們爲什麼要使用這些特殊的暗示類型。在x11下,大家可以參考x11的內部協議規定,裏面有描述。在win32下,我想主要是要使用裸窗口。裸窗口的使用在各個平臺下還是十分常見的,例如:我們常見的msn信件到來通知,就是這樣一個窗口;或者當我們需要寫一個比較怪異的窗口時,例如:windows media player裏面的那些怪異窗口,這時我們就需要去掉原有的標準窗口裝飾,並自己的用圖片描繪出窗口的樣式。

除了以上我們介紹的這些關於窗口的api以外,還有$win -> present; 設置窗口顯示在用戶面前;$win -> set_gravity ( $gravity ); 這個也是用來設置窗口最初出現時的位置,$gravity可以爲north-west、north、east等。


三.Gtk2::TextView

強大的多行文字控件,可以顯示太多種的數據,基本上如果你是想要純粹的顯示數據,或者編輯文字與圖片組成的數據流,都可以直接使用這個控件來完成。

這個控件包含幾個部分:

i. Gtk2::TextBuffer
ii. Gtk2::TextChildAnchor
iii. Gtk2::TextIter
iv. Gtk2::TextMark
v. Gtk2::TextTag
vi. Gtk2::TextTagTable
vii. Gtk2::TextView

Gtk2::TextBuffer 的目的是保存所有要顯示的數據在一個文字緩衝中。
Gtk2::TextChildAnchor 的目的是在文字緩衝中插入一個控件。
Gtk2::TextIter 的目的是操作當前緩衝所處的位置。
Gtk2::TextMark 的目的是在文字緩衝中保存一個位置,比較像我們在Html中的書籤功能,我們可以隨意的回到這個位置。
Gtk2::TextTag 的目的是爲文字緩衝中的文字添加一個顯示標籤,例如:改變文字的顯示顏色,改變文字的字體,或者文字大小。
Gtk2::TextTagTable 的目的是保存所有 Gtk2::TextTag 標籤。每個 Gtk2::TextBuffer 緩衝只對應於一個Gtk2::TextTagTable 。
Gtk2::TextView 的目的是顯示文字緩衝中的數據。

我們看到了,要實現一個多行文字控件,需要多個模塊配合起來使用,我們大概來描述一下這個過程:一個Gtk2::TextView 控件,它的顯示數據(文字與圖片)是要存儲在Gtk2::TextBuffer 建立的緩衝中,而這個緩衝中的數據我們可以爲其添加Gtk2::TextTag ,從而爲緩衝數據(文字)設定顯示格式,或者我們用 Gtk2::TextChildAnchor 可以在緩衝中添加其他的控件來顯示。當我們想要操縱我們在緩衝中的位置時,我們可以使用 Gtk2::TextIter ,例如:向前移動一行,向後移動一個字母。當我們想要在緩衝中標記一個位置,然後可以快速的移動到這個位置去顯示,我們可以使用 Gtk2::TextMark 。

OK,我們現在來個實例來說明一下:


my $sw = Gtk2::ScrolledWindow -> new ();
$sw -> set_policy ( 'automatic' , 'automatic' );
my $textview = Gtk2::TextView -> new ();
$textview -> can_focus (1);
$textview -> set_editable (0);
$textview -> set_left_margin (10);
$textview -> set_right_margin (10);
$textview -> set_wrap_mode ( 'GTK_WRAP_WORD_CHAR' );
my $tab_table = Gtk2::TextTagTable -> new ();
my $text_buffer = Gtk2::TextBuffer -> new ( $tab_table );
$textview -> set_buffer ($text_buffer );
$sw -> add ( $textview );

 

一個textview控件的實例:



 

這個實例裏我們首先建立了一個 Gtk2::ScrolledWindow 控件,這個控件的目的是爲了產生滾動條。當我們要顯示的數據比 Gtk2::TextView 的窗口大時,我們就需要滾動條。這裏我們設置$sw -> set_policy ( 'automatic' , 'automatic' ); 代表了水平滾動條與垂直滾動條都是自動(automatic)出現的,也就是如果要顯示的數據超出了窗口,這纔出現滾動條,否則將不顯示滾動條。還有一點要注意的是:$sw -> add ( $textview ); 滾動條控件要包含文字控件。

然後,我們建立了一個 Gtk2::TextView 控件,並設置它的屬性。

  • $textview -> can_focus (1); 表示這個文字控件可以接受輸入。
  • $textview -> set_editable (0); 表示這個文字控件的內容不能被編輯,也就是說我們不能隨意的插入文字。如果設置爲1,那麼我們就可以編輯文字控件的內容,就像一個記事本那樣。
  • $textview -> set_left_margin (10); 設置文字控件左面的空白大小爲10像素,這個空白是說該控件與窗口邊界(或者另一個控件)之間的距離,主要是美觀的需要。
  • $textview -> set_wrap_mode ( 'GTK_WRAP_WORD_CHAR' ); 設置文字換行方式爲遇到窗口邊界就自動換行。其他的選項還有:none,不自動換行;

然後,我們又建立了一個 Gtk2::TextTagTable 表。接着建立了一個Gtk2::TextBuffer 並將該Gtk2::TextTagTable 表賦予文字緩衝。(這裏其實有更簡單的方式,我們可以直接使用Gtk2::TextBuffer -> new (); ,這樣會自動建立一個tagtable。)

最後,我們將 Gtk2::TextView 的文字緩衝設置爲剛建立的那個緩衝。至此,初始化的工作我們就全部完成了。接下來,我們要來看看如何向這樣一個文字控件中插入數據。

看例子:


use Gtk2::Pango;
$text_buffer -> set_text ( "" );
my $iter = $text_buffer -> get_iter_at_offset (0);
$text_buffer -> insert_txt ($iter , "test test test\n" );
$text_buffer -> create_tag ( "bold" , weight => PANGO_WEIGHT_BOLD );
$text_buffer -> insert_with_tags_by_name ( $iter , "test test" , "bold" );
my $pixbuf = Gtk2::Gdk::Pixbuf -> new_from_file ( 'test.jpg' );
$text_buffer -> insert_pixbuf ( $iter , $pixbuf );
my $input = Gtk2::Entry -> new;
my $anchor = $text_buffer -> create_child_anchor ( $iter );
$textview -> add_child_at_anchor ( $input , $anchor );
$textview -> show_all ();

 

首先,我們 use Gtk2::Pango; ,這是爲了使用下面的 PANGO_WEIGHT_BOLD 這樣的常量定義。

$text_buffer -> set_text ( "" ); 先將緩衝清空。my $iter = $text_buffer -> get_iter_at_offset (0); 將我們的iter移動到緩衝的開頭處。這兩步都是一個文字緩衝開始插入數據前最好執行的兩步,因爲一般一個文字緩衝都要重複的使用,所以在開始一次新的使用前做一下這些工作可以保證緩衝的正確運行。

這裏要說明一下iter。iter這裏代表的是一個在緩衝中的當前位置,當插入任何數據時,都要從這個iter的當前位置開始插入。由於可以在緩衝中插入文字、圖片、控件等多種數據,所以iter的計算是由gtk+的內部完成的,我們只需要關心如何使用iter就可以了。

接下來,$text_buffer -> insert_txt ($iter , "test test test\n" ); 我們插入一段文字:"test test test\n"。這裏還有點說明:這裏的$iter值當插入完成時會被自動的增加到插入的結尾處,以便於下一次數據的插入。所以,下一次插入數據時我們還可以直接使用 $text_buffer -> insert_txt ($iter , "test test test\n" ); 就可以了,而不用管$iter值,因爲每次插入後$iter值都被自動更新了。

接着,我們 $text_buffer -> create_tag ( "bold" , weight => PANGO_WEIGHT_BOLD ); 建立了一個粗體的顯示標籤,將這個標籤的名稱標爲:"bold"。這裏我們可以創建的標籤有很多種,例如:文字的顏色,字體,大小,風格,粗體,斜體,或者文字的下滑線,文字背景色,文字的背景位圖,文字的對齊方式等等。

$text_buffer -> insert_with_tags_by_name ($iter , "test test" , "bold" ); 我們插入一段文字" test test",並將標籤名稱爲"bold"的標籤賦給這段文字,這樣這段文字就會以粗體的方式顯示。

接下來,my $pixbuf = Gtk2::Gdk::Pixbuf -> new_from_file ( 'test.jpg' ); 我們讀取了一個圖像文件,建立了一個新的pixbuf。$text_buffer -> insert_pixbuf ( $iter , $pixbuf ); 我們將這個圖片插入到了文字緩衝中。

最後,my $input = Gtk2::Entry -> new; 建立了一個新的單行文字輸入控件。 my $anchor = $text_buffer -> create_child_anchor ( $iter ); 在緩衝的當前位置下建立了一個子錨。 $textview -> add_child_at_anchor ( $input , $anchor ); 在$textview 文字顯示控件中添加新建立的文字輸入控件到子錨上。 $textview -> show_all (); 顯示所有的數據。當在緩衝中插入一個控件時,最好調用一下,否則控件可能會不顯示出來。

Gtk2::TextView文字控件的功能很強,使用起來也比較的方便,所以可以用來實現一些較爲常規的功能,如:編寫一個文字編輯器,一個簡單的顯示軟件等等。筆者的perl web browser項目"shellweb"最初就是使用這個控件來顯示html數據的。如果大家感興趣的話可以參考其中的用法。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章