分頁框(notebook)是一種讓你分頁管理視窗元件的容器,如果你想要做出類似Firefox或IE那種分頁的功能,就會使用到分頁框。這一篇文章的內容說明ttk::notebook的使用方法。
32.1 建立分頁框
以下是一個簡單的例子,它會建立一個分頁框然後再建立一個分頁,並在分頁裡放入一個ttk::treeview元件,程式碼如下:這個程式的1~2行建立一個分頁框元件,4~6行建立一個treeview元件,然後在裡面加入兩個測試用的項目,最後一行使用分頁框的add命令建立一個新的分頁,並把剛剛建立的treeview放在新的分頁裡,後面的-text選項可以用來設定新分頁的文字標題。
這邊有2個重點要注意!! 第一,凡是放在分頁框裡的視窗元件,儘可能以分頁框的path或是Root視窗作為父親,否則在某些情況下放在分頁裡的視窗元件可能會顯示不出來。例如上一個範例treeview的path是.nb.tv,它就是以分頁框的path也就是.nb做為父親。第二,被加入分頁的視窗元件的path可以當做分頁ID,以上面的例子來看分頁1的ID就是.nb.tv,往後如果要刪除或是設定分頁1都要以.nv.tv做為依據。
程式執行的畫面如下:
圖 32-1
事實上真正開發開程式我們不會像上面,把整個treeview放在分頁裡,因為這樣一個分頁就變成只能放一個視窗元件,比較好的做法是像下方的例子,先建立一個空的frame放進分頁,然後再從這個frame上放置其它的視窗元件。
這個例子建立一個空的frame放進第二個分頁裡,然後在這個空的frame裡再加進標籤、文字方塊及按鈕等,三個視窗元件。它執行起來像這樣:
圖 32-2
除了使用add命令來建立分頁之外,也可以使用insert命令,兩者不同的是insert可以指定新分頁的顯示位置。如果把上一個範例的
換成
這樣分頁2就會顯示在分頁1的前面,執行畫面像這樣:
圖 32-3
insert命令後面的位置必需是一個0以上的整數,或是使用end來表示最後一個位置。
32.2 隱藏及刪除分頁
如果你想要暫時隱藏某一個分頁,可以使用分頁框的hide命令,例如想要把上一個例子裡的treeview分頁變隱藏可以這樣:如果要重新顯示的話只要再執行一次add命令就可以了,被隱藏的分頁會重新在之前的位置顯示。
下面是另一個例子,我用兩個按鈕來示範如何顯示及隱藏分頁。
這個程式執行起來像這樣,下方的兩個按鈕可以控制分頁1顯示或隱藏。
圖 32-4
如過你希望移除某一個分頁,可以使用forget命令,例如:
這forget命令會移除放置.nb.tv的分頁。注意哦!! .nb.tv本身並不會被destroy,所以你還是要自己銷毀它,像這樣:
32.3 其它常用的分頁框命令
tabs命令可以用清單的方式取得所有分頁的ID,例如:這個程式的puts會輸出「.nb.tv1 .nb.tv2」,當然你要計算目前有多少分頁的話只要用llength來計算tabs命令的回傳結果就可以了,像這樣:
如果你想要用程式去選取某個分頁,可以用select命令,例如:
這樣的話分頁2就會被選取。如果select命令後面沒有加分頁ID,則可以取得目前選中的分頁ID,例如:
如果你希望修改分頁上的文字標籤或其它選項,可以用tab命令,例如,下方的程式片段會把分頁1的文字標籤改為Tab1。
tab命令也可以用來取得分頁的選項值,例如:
這樣會輸出.nb.tv1分頁的文字標籤。
32.4 其它分頁常用的選項
每一個分頁除了可以指定文字標籤之外,還可以使用-image指定分頁的小圖示,另外-compound選項可以用來指定圖示及文字顯示的相對位置。下面是一個使用的例子:執行的畫面如下分頁1的前面多了一個小圖示。
圖 32-5
另外分頁的-padding選項可以用來調整,放置視窗元件周圍的額外空間,例如:
在下方的執行畫面裡treeview的周圍多了一層的額外空間。
圖 32-6
分頁框也提供了cget及configure等標準的視窗元件命令,它們的用法請參考這一章的說明。
按右上方的「#」號切換側邊欄
14 個意見
米粒 | 2010年1月15日 晚上10:03
真的找不到錯字@@
這篇我是真的有興趣喔
dai | 2010年1月15日 晚上10:17
因為我寫完都會再查看一次錯字 呵呵 ~
Todozen | 2013年4月10日 上午11:24
Dear Dai~請問一下,如上面notebook的範例,若分頁1和分頁2內呼叫同一個proc abc,且這個proc abc內只是請你輸入字串"123456",但是為何當在分頁1輸入時,同時間分頁2也會受影響而有相同的輸入值呢?該如何解決這個問題呢?thanks.
dai | 2013年4月10日 上午11:51
嗯 ~ 也許需要你把程式貼上來,看過才知道 ~
Todozen | 2013年4月10日 中午12:36
Dai~如下所示,麻煩你了,thanks.
proc abc {w} {
set ::value ""
set lbl [ttk::label $w.lbl -text "Input"]
set txt [ttk::entry $w.txt -textvariable ::value]
set btn [ttk::button $w.btn -text "Exit" -command {exit}]
grid $lbl $txt
grid $btn
}
ttk::notebook .nb
pack .nb -expand 1 -fill both
set fme1 [ttk::frame .nb.f1]
.nb add $fme1 -text "1"
abc .nb.f1
set fme2 [ttk::frame .nb.f2]
.nb add $fme2 -text "2"
abc .nb.f2
dai | 2013年4月10日 下午3:43
因為 ::value 是全域變數,所以fme1, fme2 裡的 txt 參考到了相同的變數。
改這樣試試 :
array set ::values [list] ;# 注意這行
proc abc {w} {
set ::value ""
set lbl [ttk::label $w.lbl -text "Input"]
set txt [ttk::entry $w.txt -textvariable ::values($w)] ;# 注意這行
set btn [ttk::button $w.btn -text "Exit" -command {exit}]
grid $lbl $txt
grid $btn
}
ttk::notebook .nb
pack .nb -expand 1 -fill both
set fme1 [ttk::frame .nb.f1]
.nb add $fme1 -text "1"
abc .nb.f1
set fme2 [ttk::frame .nb.f2]
.nb add $fme2 -text "2"
abc .nb.f2
Todozen | 2013年4月10日 下午5:20
Dai~我試過是ok的,不過再請教一下,我沒有使用global ::value,為何::value會是全域變數呢?另外若::value要設定初始值的話寫成array set ::values [list $w "123456"]是否正確呢?(我有先試過好像可以)thanks.
dai | 2013年4月10日 晚上8:47
請參考第10及14章的內容。
豬事大吉 | 2013年5月8日 下午4:21
請問"分頁1"那個字體大小可以修改嗎?
dai | 2013年5月8日 下午6:45
這個我沒有試過也
但 應該可以用ttk::style的命令來改
豬事大吉 | 2013年5月9日 下午1:37
謝謝dai提供方向
讓小豬一下就解決了~ 順便分享一下
ttk::style configure TNotebook.Tab \
-font {arial 14 bold} \
-foreground blue
dai | 2013年5月9日 下午4:00
收到了,謝謝分享~
Mike | 2014年12月19日 下午5:31
這邊可以方便再請問一下,分頁框這種東西可以垂直的分頁嗎?
看預設好像都是水平的,我也找不到哪邊可以把上面那個Tab改成垂直的說。
如果不可以的話,我可以把那個小Tab全部拿掉,然後另外用Button來控制分頁嗎?
匿名 | 2014年12月20日 下午6:37
垂直的tab沒有這麼用過~~
留下您的意見