<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                ### 8.2.3 常見 GUI 構件的用法 本節介紹一些最常見的 GUI 構件的用法。為了便于討論,我們使用 Python 的命令行界 面①來交互式地執行語句,這樣可以執行一條語句就立即看到其執行效果。讀者也可以一邊 閱讀本書,一邊在計算機上動手練習。 GUI 編程首先要做的是導入 Tkinter 模塊并創建根窗口: ``` from Tkinter import * root = Tk() ``` 可以看到,屏幕上立即出現一個根窗口,接下去就可以向根窗口中加入子構件了。 當所有構件添加完畢,通過執行下列語句來啟動主循環: ``` root.mainloop() ``` 這時可以看到 Python 命令行界面的&gt;&gt;&gt;提示符沒有了,表明現在 Tkinter 程序接管了控制權。 當最后關閉根窗口時,所有構件也都同時撤銷。 下面演示各種構件的用法時,我們既可以在同一個根窗口中演示多個構件的用法,也可以每次演示新構件時重新創建根窗口。由于這兩種做法并不影響本節的主旨,為了行文簡潔, 我們對此不加區別,以上這幾個導入模塊、創建根窗口和進入主循環的步驟也不重復列出, 讀者練習時可根據需要補上有關步驟。 標簽 標簽用于在窗口中顯示文本信息,Tkinter 定義了類 Label 來支持標簽構件的創建。創建 標簽時需要指定父構件和文本內容,前者由 Label 構造器的第一個參數指定,后者用屬性 text 指定。例如前面已經見過的: ``` >>> aLabel = Label(root,text="Hello World") ``` 這條語句創建了一個標簽構件實例,但該構件在窗口中仍然不可見。為使構件在窗口中 可見,需要調用布局管理器對該構件進行位置安排。仍然如前面已經見過的,下面這條語句 對標簽對象 aLabel 調用方法 pack,意為用 Pack 布局管理器來安排這個標簽的位置: > ① Python 的 GUI 環境 IDLE 本身是用 Tkinter 寫的程序,因此無法在 IDLE 中交互式地創建 Tkinter 窗口和其 他構件。 ``` >>> aLabel.pack() ``` 于是標簽在根窗口中得到顯示,同時根窗口的大小也改變了——變成剛好可以放置新加入的 標簽構件(參見圖 8.4)。這正是 Pack(“打包”)的效果,即所有東西以緊湊的方式布置。Pack 布局管理器簡單易用,但不適合進行復雜布局,我們后面會介紹其他布局管理器。 標簽構件除了 text 屬性之外,還有其他許多屬性。上例中只為標簽的 text 屬性提供了值 “Hello World”,其他屬性(如字體、顏色等)都使用缺省值。下面這條語句為標簽的更多屬 性設置屬性值: ``` >>> Label(root,text='Text in Red',fg='red',width=40).pack() ``` 其中屬性 fg 和 width 分別表示標簽文本的顏色和標簽的寬度,效果見圖 8.6: ![](https://box.kancloud.cn/2016-02-22_56cafce5039ad.png) 圖 8.6 標簽構件 注意,上面這條語句采用了將對象創建和對象方法調用結合在一起的語法①:先用構造器 Label(…)創建一個標簽對象,然后直接對這個對象調用方法 pack(),而不是先定義一個變 量作為新建對象的引用,然后通過變量引用來調用對象方法。顯然,對象創建與對象方法調 用合并的寫法不適合需要多次引用一個對象的場合。另外,初學者容易犯的一個錯誤是寫成: ``` w = Label(...).pack() ``` 這條語句實際上是將 pack 的返回結果(None)賦值給 w,而非 Label(…)的返回結果(新建 的標簽對象)。為了避免這類微妙的錯誤,最好將創建構件和構件布局的語句分開。 如果希望在程序運行過程中改變標簽的文本內容,可以利用 8.2.2 中介紹的設置構件對象 屬性的方法來重新設置標簽對象的 text 屬性值。很多 GUI 應用程序的窗口底部都有一個狀態 欄(例如 Word 窗口的狀態欄),用來顯示程序的一些狀態信息,這可以用標簽構件來實現, 狀態的變化可以通過修改標簽對象的 text 屬性值來實現。 按鈕 按鈕也叫命令按鈕,是界面中的一個矩形區域(通常長度大于高度),矩形內部是描述性 的標題(例如常見的“確認”和“取消”)。對按鈕的操作是用鼠標點擊,其作用是命令程序 去執行預定義的操作。按鈕可以說是圖形界面中最常見的構件,是用戶命令程序執行某項任 務的基本手段。 下列語句在根窗口 root 中創建了一個按鈕構件: ``` >>> quitButton = Button(root,text="Quit",command=root.quit) ``` 對按鈕構件來說是最重要的屬性是 command,它用于將按鈕與某個函數或方法進行關 聯。傳遞給 command 的值是一個函數(或方法),該函數就是點擊按鈕時要執行的操作。上 例中將按鈕與根窗口 root 的內建方法 quit 相關聯,其功能是退出主循環。注意,傳遞給 command 屬性的是函數對象,函數名后不能加括號,切記 f 是函數對象,而 f()是函數調用(的 結果)。 按鈕構件在窗口中的位置也需要用布局管理器來安排,例如用 pack 布局管理器: ``` >>> quitButton.pack() ``` 從顯示結果(圖 8.7)可以看到,與前述標簽的情形一樣,quitButton 按鈕在窗口中以緊湊方 式布置并變得可見。由于 pack 方法是在 Tkinter 的基類中定義的,而所有構件都是這個基類 的子類,從而都繼承了這個方法,所以對標簽和按鈕以及其他各種構件都可以調用 pack 方法。 > ① 參見第 7 章。 ![](https://box.kancloud.cn/2016-02-22_56cafce512b05.png) 圖 8.7 按鈕構件 為了驗證按鈕的功能,我們先進入主循環: ``` >>> root.mainloop() ``` 然后點擊 Quit 按鈕,可以看到又回到了 Python 解釋器的提示符狀態,這就是 root.quit 方法 的作用。 實際應用程序中通常由程序員自己定義與按鈕相關聯的函數,以實現某種操作。下面這 個例子為按鈕定義了一個簡單的顯示信息的函數: ``` >>> def hiButton(): ... print 'hi there' ... >>> Button(root,text='print',command=hiButton).pack() ``` 如果點擊按鈕,會看到在控制臺顯示信息“hi there”。 按鈕構件還有其他許多屬性,如寬度、文本顏色、按鈕邊框的 3D 風格、活動狀態等等, 更多細節可參看本章后面的附錄。 勾選鈕 勾選鈕也稱為勾選框或復選框,用于向用戶提供一個選項,用戶對該選項有“選中”或 “不選”兩種選擇。勾選鈕在外觀上由一個小方框和一個相鄰的描述性標題組成,未選中時 方框為空白,選中時方框中出現勾號,再次選擇一個已打勾的勾選鈕將取消選擇。對勾選鈕 的選擇操作一般是用鼠標點擊小方框或標題。Tkinter 的類 Checkbutton 實現了勾選鈕構件, 其最簡單的用法如下: ``` >>> Checkbutton(root,text="A Choice").pack() ``` 如果程序中需要查詢和設置選項的狀態,可以將勾選鈕與一個控制變量關聯。控制變量 是 IntVar 類的實例,值為 1 或 0,分別對應選中和未選中狀態。用法如下: ``` >>> v = IntVar() >>> Checkbutton(root,text="A Choice",variable=v).pack() ``` 程序中可以通過 v.get()和 v.set()來查詢或設置勾選鈕的狀態。 在實際應用中,通常將多個勾選鈕組合為一組,為用戶提供多個相關的選項,用戶可以選中 0 個、1 個或多個選項。例如: ``` >>> Checkbutton(root,text="Math").pack() >>> Checkbutton(root,text="Python").pack() >>> Checkbutton(root,text="English").pack() ``` 執行效果如圖 8.8 所示。為了在程序中獲得各勾選鈕的狀態,可以為每個勾選鈕關聯一個不 同的控制變量。 ![](https://box.kancloud.cn/2016-02-22_56cafce522163.png) 圖 8.8 勾選鈕構件 圖 8.8 中各勾選鈕排列的不太美觀,這是因為 pack 在布局時默認采用了居中對齊方式。 布局管理器提供了其他對齊方式,詳見 8.2.4。此外,在實際 GUI 設計中,為了表示一組勾 選鈕的相關性,通常會用一個框架容器將它們組合起來(參見圖 8.11)。 單選鈕 和勾選鈕類似,單選鈕也是列出選項供用戶選擇,并且通常也是由若干個單選鈕構成一 組來提供多個相關的選項。但與勾選鈕不同的是,同組的單選鈕在任意時刻只能有一個被選 中;每當換選其他單選鈕時,原先選中的單選鈕即被取消①。 單選鈕的外觀是一個小圓框加上相鄰的描述性標題,未選中時圓框內是空白,選中時圓 框中出現一個圓點。對單選鈕的選擇操作是用鼠標點擊小圓框或標題。Tkinter 提供的 Radiobutton 類可支持單選鈕的創建。例如最簡單的單選鈕可用如下語句創建: ``` >>> Radiobutton(root,text="One").pack() ``` 如上所述,實際應用中都是將若干個相關的單選鈕組合成一個組,使得每次只能有一個 單選鈕被選中。為了實現單選鈕的組合,可以先創建一個 IntVar 或 StringVar 類型的控制變量, 然后將同組的每個單選鈕的 variable 屬性都設置成該控制變量。由于多個單選鈕共享一個控 制變量,而控制變量每次只能取一個值,所以選中一個單選鈕就會導致取消另一個。 為了在程序中獲取當前被選中的單選鈕的信息,可以為同組中的每個單選鈕設置 value 屬性的值。這樣,當選中一個單選鈕時,控制變量即被設置為它的 value 值,程序中即可通 過控制變量的當前值來判斷是哪個單選鈕被選中了。還要注意,value 屬性的值應當與控制變 量的類型匹配:如果控制變量是 IntVar 類型,則應為每個單選鈕賦予不同的整數值;如果控 制變量是 StringVar,則應為每個單選鈕賦予不同的字符串值。下面這個例子將三個單選鈕組 合成一組: ``` >>> v = IntVar() >>> v.set(1) >>> Radiobutton(root,text="One",variable=v,value=1).pack() >>> Radiobutton(root,text="Two",variable=v,value=2).pack() >>> Radiobutton(root,text="Three",variable=v,value=3).pack() ``` 其中三個單選鈕共享一個 IntVar 型的控制變量 v,且分別設置了值 1、2、3。第二行 v.set(1) 的作用是設置初始默認選項。上述語句序列的執行效果如圖 8.9 所示。另外,圖中三個單選 鈕是居中對齊,不太美觀,可以用布局管理器設置對齊方式,詳見 8.2.4。 ![](https://box.kancloud.cn/2016-02-22_56cafce532345.png) 圖 8.9 單選鈕構件 文本編輯區 文本編輯區是允許用戶輸入和編輯數據的區域,用戶使用鍵盤在這個區域中輸入文本, 輸入過程中隨時可以進行編輯,如光標定位、修改、插入等。有的文本編輯區只允許輸入一 行文本,有的則允許輸入多行。文本編輯區一般可以設置行和列的大小,并且可以通過滾動 條來顯示、編輯更多的文本。 > ① 單選鈕的英文是 radio button,名稱源自收音機中預置電臺按鈕,選一個臺的同時就取消了另一個臺。 Tkinter 提供的 Entry 類可以實現單行文本的輸入和編輯,不妨稱之為錄入框。下面的語 句創建并布置一個錄入框構件: ``` >>> Entry(root).pack() ``` 運行結果是在窗口中出現一行空白區域,點擊此區域后會出現一個閃爍的光標,這時就可以 在其中輸入文本了。圖 8.10 是輸入了一些文本后的效果: ![](https://box.kancloud.cn/2016-02-22_56cafce540a1f.png) 圖 8.10 錄入框構件 當用戶輸入了數據之后,應用程序顯然需要某種手段來獲取用戶的輸入,以便對數據進行處理。為此,可以通過 Entry 對象的 textvariable 屬性將錄入框與一個 StringVar 類型的控制 變量相關聯,具體做法如下: ``` >>> v = StringVar() >>> e = Entry(root,textvariable = v) >>> e.pack() ``` 此后程序中就可以利用 v.get()來獲取錄入框中的文本內容。假設用戶在錄入框內鍵入了文 本“hello”,那么就有 ``` >>> print v.get() hello ``` 另外,程序中還可以通過 v.set()來設置錄入框的內容: ``` >>> v.set('new text') ``` 可以看到錄入框中的文本立即變成了“new text”。 很多應用程序利用錄入框作為用戶登錄系統時輸入用戶名和密碼的界面元素,其中密碼錄入框一般不回顯用戶的輸入,而是用“*”代替,這在 Tkinter 中很容易做到,只需將錄入 框對象的 show 屬性設置為“*”即可: ``` e.config(show='*') ``` 除了 Entry 類,Tkinter 還提供一個支持多行文本錄入與編輯的文本區構件類:Text。兩 者的用法是類似的: ``` >>> Text(root).pack() ``` 運行結果是在窗口中出現了一個多行的空白區域,在此區域可輸入、編輯多行文本。Text 構 件的用途非常多,用法也比 Entry 復雜,這里就不詳細介紹了。 框架 利用前面幾節介紹的基本構件雖然能夠實現簡單的圖形界面,但不足以搭建出美觀的復 雜圖形界面。為了將基本構件在界面中有層次地組織起來,還需要構件容器。如我們在 8.1.2 中描述的,框架就是一種容器,其主要用途是將一組相關的基本構件組合成為一個“復合” 構件。利用框架對窗口進行模塊化分隔,即可建立復雜的圖形界面結構。每個框架都是一個 獨立的區域,可以獨立地對其中包含的子構件進行布局。 Tkinter 提供了 Frame 類來創建框架構件,框架的寬度和高度分別用 width 和 height 屬性 來設置,框架的邊框粗細用 bd(或 border、borderwidth)屬性來設置(默認值為 0,即沒有 邊框),邊框的 3D 風格用 relief 屬性來設置(默認是與環境融合的 flat 風格,其他可選的值 還有 groove、sunken、raised 和 ridge)。框架構件和基本構件一樣需要先創建再布局,例如: ``` >>> f = Frame(root,width=300,height=400,bd=4,relief="groove") >>> f.pack() ``` 這個框架的邊框風格是 groove,讀者可以試試其他邊框風格分別是什么樣子的。順便說一下, relief 屬性也適用于按鈕構件。 下面這個例子演示了如何將框架用作容器來組合構件,圖 8.11 是其執行效果。 ``` >>> f = Frame(root,bd=4,relief="groove") >>> f.pack() >>> Checkbutton(f,text="Math").pack() >>> Checkbutton(f,text="Python").pack() ``` ``` >>> Checkbutton(f,text="English").pack() ``` ![](https://box.kancloud.cn/2016-02-22_56cafce554080.png) 圖 8.11 利用框架組合構件 除了作為容器來組合多個構件的用途,框架還可用于圖形界面的空間分隔或填充,例如: ``` >>> Label(root,text="one").pack() >>> Frame(height=2,bd=1,relief="sunken").pack(fill=X,pady=5) ``` ``` >>> Label(text="two").pack() ``` 其中第二行語句定義的框架只起著分隔兩個標簽構件的作用,該框架在根窗口中以 x 方向填 滿(fill=X)、y 方向上下各填充 5 個像素空間(pady=5)的方式進行 Pack 布局。效果見圖 8.12: ![](https://box.kancloud.cn/2016-02-22_56cafce5660cc.png) 圖 8.12 利用框架分隔構件 后文(見 8.4.1)會介紹,我們經常將 GUI 應用程序封裝成類,尤其是封裝成 Frame 的 子類。這樣做的好處是可以將程序邏輯與用戶界面融為一體,界面元素之間的交互情況對外 部是隱藏的。 菜單 菜單也是 GUI 最常用的構件之一。就像飯店里用的菜單一樣,菜單構件是一個由許多菜 單項組成的列表,每個菜單項表示一條命令或一個選項。用戶通過鼠標或鍵盤選擇菜單項, 以執行命令或選中選項,由此可見菜單兼具命令按鈕、勾選鈕和單選鈕的功能。另一方面, 菜單又不像大量命令按鈕、勾選鈕和單選鈕那么占空間,因為菜單在不用時通常是“合上” 的,在界面中只是一個占用極少空間的菜單按鈕,直到用戶點擊菜單按鈕才會展開整個菜單。 圖形界面中一般有多個菜單,它們通常以相鄰的方式布置在一起,形成窗口的菜單欄,并且 一般置于窗口頂端。 除了菜單欄里的菜單,GUI 中還常用一種彈出式菜單,這種菜單平時在界面中是不可見 的,當用戶在界面中點擊鼠標右鍵時才會“彈出”一個與點擊位置相關的菜單。 有時候菜單中一個菜單項的作用是展開另一個菜單,形成“級聯式”菜單。 Tkinter 提供 Menu 類用于創建菜單構件,具體用法是先創建一個菜單構件實例,并與某 個窗口(根窗口或者頂層窗口)進行關聯,然后再為該菜單添加菜單項。與根窗口關聯的菜 單實際上構成了根窗口的菜單欄。菜單項可以是簡單命令、級聯式菜單、勾選鈕或一組單選 鈕,分別用 add_command、add_cascade、add_checkbutton 和 add_radiobutton 來添加。為了使 菜單結構清晰,還可以用 add_separator 在菜單中添加分割線。 例如,下列語句以交互方式創建了一個菜單(假設已經創建了根窗口 root): ``` >>> m = Menu(root) >>> root.config(menu=m) >>> m.add_command(label="File") >>> m.add_command(label="Edit") ``` 其中第一條語句創建菜單實例 m(作為 root 的子構件);第二條語句將 root 的 menu 屬性設置 為 m ①,這導致將 m 布置于根窗口的頂部,形成菜單欄;第三、四條語句創建 m 的兩個命 令菜單項。執行結果如圖 8.13 所示。另外從上面的語句可以看到,菜單構件與前面介紹的構 件都不同,不需要調用布局管理器來使之可見,Tkinter 會自動布局并顯示菜單。 ![](https://box.kancloud.cn/2016-02-22_56cafce576173.png) 圖 8.13 菜單構件 上面這個例子其實沒什么用,因為沒有為命令菜單項指定相應的處理代碼。另外,在實際應用中,窗口菜單欄里的菜單項通常是一個級聯菜單,而不是簡單命令菜單項。下面看一 個更實用的例子: 【程序 8.4】eg8_4.py ``` from Tkinter import * def callback(): print "hello from menu" root = Tk() m = Menu(root) root.config(menu = m) filemenu = Menu(m) m.add_cascade(label="File", menu=filemenu) filemenu.add_command(label="New", command=callback) filemenu.add_command(label="Open...", command=callback) filemenu.add_separator() filemenu.add_command(label="Exit", command=callback) helpmenu = Menu(m) m.add_cascade(label="Help", menu=helpmenu) helpmenu.add_command(label="About...", command=callback) mainloop() ``` > ① 也可采用 root['menu'] = m 的語法,參見 8.2.3.1。 程序 8.4 首先以根窗口為父構件創建菜單構件 m,接著將 m 設置為根窗口的菜單欄;然 后以 m 為父構件創建另兩個菜單構件 filemenu 和 helpmenu,它們分別構成菜單 m 的菜單項 “File”和“Help”的級聯菜單。菜單 filemenu 又由三個命令菜單項組成(中間有一道分隔 線),菜單 helpmenu 中只有一個命令菜單項。各個菜單在界面中的位置由 Tkinter 自動布局, 不需要調用布局管理器。為了簡化程序,我們將所有命令菜單項都關聯到同一個函數 callback, 實際應用程序當然應該為每個命令編制各自的處理函數。執行本程序并點擊 File 菜單項之后 的結果如圖 8.14 所示: ![](https://box.kancloud.cn/2016-02-22_56cafce585379.png) 圖 8.14 程序 8.4 的執行結果 頂層窗口 迄今我們所寫的程序都只有一個窗口,即根窗口。如所熟知的,像 Word 之類的應用程 序是多窗口的,每打開一個文檔都新開一個窗口。為了支持多窗口應用程序,Tkinter 提供 Toplevel 類用于創建頂層窗口構件。頂層窗口的外觀與根窗口一樣,可以獨立地移動和改變 大小,并且不需要像其他構件那樣必須在根窗口中進行布局后才顯示。一個應用程序只能有 一個根窗口,但可以創建任意多個頂層窗口。例如: ``` >>> root = Tk() >>> Label(root,text="hello").pack() >>> top = Toplevel() >>> Label(top,text="world").pack() ``` 這個語句序列先創建根窗口,在根窗口中創建一個標簽,然后創建了一個頂層窗口,又在頂 層窗口中創建了一個標簽。執行結果如圖 8.15 所示。 ![](https://box.kancloud.cn/2016-02-22_56cafce5986ef.png) 圖 8.15 頂層窗口 對上例要說明的是,雖然創建 Toplevel 構件 top 時沒有指定以根窗口 root 作為父構件, 但 top 確實是 root 的子構件,因此關閉 top 并不會結束程序,因為根窗口仍在工作;但若關 閉根窗口,則包含 top 在內的整個界面都會關閉。所以頂層窗口雖然具有相對的獨立性,但 它不能脫離根窗口而存在。即使在沒有根窗口的情況下直接創建頂層窗口,系統也會自動先 創建根窗口。 與根窗口類似,可以調用 Toplevel 類的 title 和 geometry 方法來設置它的標題和大小: ``` >>> top.title('hello toplevel') >>> top.geometry('400x300') ``` 當然也可以為頂層窗口建立菜單,方法和根窗口類似,這里就不贅述了。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看