日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

簡單介紹利用TK在Python下進行GUI編程的教程

系統(tǒng) 1959 0

我想要向您介紹能想像到的開始 GUI 編程的最簡單方法,就是使用 Scriptics 的 TK 和 Tkinter 封裝器。我們將與 developerWorks 中的 “Python 中的 curses 編程” 提到的 curses 庫進行很多比較。除了 curses 實現(xiàn)文本控制臺而 TK 實現(xiàn) GUI 這一差別之外,這兩個庫有著驚人相似的接口。在使用任何一個庫之前,需要基本了解窗口和事件循環(huán),并參考可用的窗口小部件。(好,好的參考和適量的練習。)

如同關于 curses 的文章,本文僅討論 Tkinter 本身的特性。既然很多 Python 發(fā)行版都帶有 Tkinter,因此可能無需下載支持庫或其它 Python 模塊。本文后面的 參考資料 指向幾個更高級別的用戶接口窗口小部件的集合,但是您可以用 Tkinter 本身做許多事,包括構造自己的高級窗口小部件。學習基本 Tkinter 模塊將為您引入 TK 的思維方式,即使您繼續(xù)使用更高級的窗口小部件集合,這種思維方式仍十分重要。
TK 簡要描述

TK 是與 TCL 語言關系最密切、且被廣泛使用的圖形庫,TCL 語言和 TK 都由 John Ousterhout 開發(fā)。雖然 TK 于 1991 年作為 X11 庫出現(xiàn),但實際上它從那時起就被移植到每一種流行的 GUI。(它與 Python 逐漸擁有“標準”GUI 的情形相似。)現(xiàn)在,大多數(shù)流行語言和很多小型語言都有 TK 綁定(Tkinter 模塊)。

在開始之前,我必須承認:我不是瘦小枯干的 TK 編程專家。事實上,我的大部分 TK 編程經驗大約從我寫這篇文章三天前才開始。那三天并非沒有挑戰(zhàn),但是最后我覺得很好地掌握了 Tkinter。我在這里要說的是:TK 和 Tkinter 封裝器設計得都非常好,便于用戶操作,并且只是關于 GUI 編程最簡單的介紹。

從測試應用程序開始

我們將使用 Txt2Html,這個在以前很多專欄(請參閱 參考資料 )中使用的文件格式轉換程序,的封裝器作為測試應用程序。雖然可以用幾種方式運行 Txt2Html,但這里的封裝器卻要從命令行運行 Txt2Html。該應用程序以批處理進程的形式運行,并帶有指出要執(zhí)行的轉換各方面特性的命令行自變量。(以后,最好為用戶提供交互式選擇屏幕選項,以在執(zhí)行實際轉換之前引導用戶逐步選擇不同的轉換選項并提供所選選項的可視反饋。)

tk_txt2html 基于帶有下拉菜單和嵌套子菜單的頂部菜單。旁邊有詳細的實現(xiàn)說明,它看起來與在 “Python 中的 Curses 編程” 中討論的 curses 版本很相象。雖然 TK 用較少的代碼可以實現(xiàn)更多的功能,但很明顯,tk_txt2html 和 curses_txt2html 很相似。例如,在 TK 中,象菜單這樣的特性可以依靠內置的 Tkinter 類實現(xiàn),而無需從頭編寫。

除了設置配置選項之外,TK 封裝器還包括一個與 TK Text 窗口小部件一起構建的滾動幫助框(一個帶有 Message 窗口小部件的“關于”框)和一個進行 TK 動態(tài)幾何管理的歷史窗口。與大多數(shù)交互式應用程序一樣,封裝器用 TK 的 Entry 窗口小部件接受某些用戶輸入。

在進一步討論代碼之前,讓我們看一下實際運行中的應用程序。

簡單介紹利用TK在Python下進行GUI編程的教程_第1張圖片

學習基本知識

實際上,Tkinter 程序只需做三件事:
最小的 [Tkinter] 程序

            
import Tkinter # import the Tkinter module
root = Tkinter.Tk() # create a root window
root.mainloop() # create an event loop


          

這是一個完全有效的 Tkinter 程序(不要介意它沒有實際用處,因為它甚至不管理 "hello world")。該程序唯一需要做的是創(chuàng)建一些容納其根窗口的窗口小部件。這樣增強之后,無需程序員進一步干涉,該程序的 root .mainloop() 方法調用就可以處理所有用戶交互。

main() 函數(shù)

現(xiàn)在,我們看一下 tk_txt2html.py 更現(xiàn)實的 main() 函數(shù)。請注意,我更喜歡使用 John Grayson 的 import Tkinter 語句,而不是 from Tkinter import (請參閱 參考資料 中所列的他的書籍)。這不是因為我擔心名稱空間的干擾( from ... import 語句的通常警告),而是因為我想明確使用 Tkinter 類;我不想冒險將它們與我自己的函數(shù)和類相混淆)。建議您也這樣做,至少在開始時這樣做。
tk_txt2html main() 函數(shù)

            
def main():
 global root, history_frame, info_line
 root = Tkinter.Tk()
 root.title('Txt2Html TK Shell')
 init_vars()
 #-- Create the menu frame, and menus to the menu frame
 menu_frame = Tkinter.Frame(root)
 menu_frame.pack(fill=Tkinter.X, side=Tkinter.TOP)
 menu_frame.tk_menuBar(file_menu(), action_menu(), help_menu())
 #-- Create the history frame (to be filled in during runtime)
 history_frame = Tkinter.Frame(root)
 history_frame.pack(fill=Tkinter.X, side=Tkinter.BOTTOM, pady=2)
 #-- Create the info frame and fill with initial contents
 info_frame = Tkinter.Frame(root)
 info_frame.pack(fill=Tkinter.X, side=Tkinter.BOTTOM)
 # first put the column labels in a sub-frame
 LEFT, Label = Tkinter.LEFT, Tkinter.Label # shortcut names
 label_line = Tkinter.Frame(info_frame, relief=Tkinter.RAISED, borderwidth=1)
 label_line.pack(side=Tkinter.TOP, padx=2, pady=1)
 Label(label_line, text="Run #", width=5).pack(side=LEFT)
 Label(label_line, text="Source:", width=20).pack(side=LEFT)
 Label(label_line, text="Target:", width=20).pack(side=LEFT)
 Label(label_line, text="Type:", width=20).pack(side=LEFT)
 Label(label_line, text="Proxy Mode:", width=20).pack(side=LEFT)
 # then put the "next run" information in a sub-frame
 info_line = Tkinter.Frame(info_frame)
 info_line.pack(side=Tkinter.TOP, padx=2, pady=1)
 update_specs()
 #-- Finally, let's actually do all that stuff created above
 root.mainloop()


          

在這個簡單的 main() 函數(shù)中有幾件事要注意:

??? 每一個窗口小部件都有一個父代。每當創(chuàng)建窗口小部件時,傳遞給實例創(chuàng)建的第一個自變量是新的窗口小部件的父代。
??? 如果有其它窗口小部件創(chuàng)建自變量,將通過名稱傳遞它們。Python 的這一特性給我們以指定選項或允許它們取缺省值的極大靈活性。
??? 有幾個窗口小部件實例 (Frame) 是全局變量??梢酝ㄟ^在函數(shù)間傳遞變量來使它們成為本地變量,以便維護代碼范圍的理論純潔性,但是與它的實際用處相比過于麻煩。另外,使這些基本的 UI 元素全局化強調了這樣一個事實:它們可以在整個函數(shù)中使用。但是,要確保對自己的全局變量使用良好的命名規(guī)范。(事先給您一個警告,Python 人員看起來討厭匈牙利符號。)
??? 創(chuàng)建完窗口小部件之后,我們調用一個幾何圖形管理器來讓 TK 知道在哪里放置窗口小部件。TK 在計算細節(jié)信息時有許多魔力,特別是當調整窗口大小或動態(tài)添加窗口小部件時更是如此。但是在任何情況下,都需要讓 TK 知道使用哪套咒語。

應用幾何圖形管理器

TK 提供三個幾何圖形管理器: .pack() 、 .grid() 和 .place() 。雖然 .place() 可用于精細(換句話說,非常復雜)的控制,但 tk_txt2html 只使用頭兩個。大多數(shù)時候,您將使用 .pack() 。

當然,可以不帶自變量來調用 .pack() 方法。但是如果那樣做,窗口小部件可能會在顯示屏幕的某處結束,您可能也想為 .pack() 提供一些提示。這些提示中最重要的是 side 自變量??赡艿闹凳?LEFT、RIGHT、TOP 和 BOTTOM(請注意這些是 Tkinter 名稱空間中的變量)。

.pack() 的許多魔力來自可以將窗口小部件嵌套這一事實。特別的,除了作為其它窗口小部件的容器(它有時顯示不同類型的邊界)之外,F(xiàn)rame 窗口小部件幾乎不作什么。這樣,就可以很方便地在所希望的方向排列幾個框架,然后在每個框架中添加其它窗口小部件。按照調用框架(以及其它窗口小部件)的 .pack() 方法的順序來排列它們。因此,如果兩個窗口小部件都請求 side=TOP ,則滿足先進入的請求。

tk_txt2html 還偶爾使用 .grid() 。grid 幾何圖形管理器用可視的坐標線覆蓋父代窗口小部件。當窗口小部件調用 .grid(row=3, column=4) 時,它請求其父代將它放在第三行第四列上。通過查看父代的所有子代的請求來計算父代的總行數(shù)和總列數(shù)。

別忘了對自己的窗口小部件應用幾何圖形管理器,以免在顯示屏幕上看不到它們時后悔莫及。


菜單

Tkinter 能輕易生成菜單。雖然我們在這里使用十分簡單的示例,但是如果愿意,還可以用不同的字體、圖形、復選框和各種別致的子代窗口小部件來填充菜單。在我們的示例中,tk_txt2html 的菜單全部用我們在上面所見的行創(chuàng)建。

menu_frame.tk_menuBar(file_menu(), action_menu(), help_menu())

這行本身可能有些神秘。大多數(shù)必須完成的工作位于名為 *_menu() 的函數(shù)中。讓我們看一下最簡單的示例。
創(chuàng)建下拉菜單

            
def help_menu():
 help_btn = Tkinter.Menubutton(menu_frame, text='Help', underline=0)
 help_btn.pack(side=Tkinter.LEFT, padx="2m")
 help_btn.menu = Tkinter.Menu(help_btn)
 help_btn.menu.add_command(label="How To", underline=0, command=HowTo)
 help_btn.menu.add_command(label="About", underline=0, command=About)
 help_btn['menu'] = help_btn.menu
 return help_btn


          

下拉菜單是將 Menu 小窗口部件作為子代的 Menubutton 小窗口部件。 .pack() (或 .grid() 等)將 Menubutton 排列在適當?shù)奈恢?。Menu 小窗口部件用 .add_command() 方法添加項。(請注意上面為 Menubutton 的目錄所作的奇怪分配。不要問為什么,跟著我這樣做并在您自己的代碼中也這樣做即可。)


獲得用戶輸入

下面將看到的示例演示 Label 小窗口部件 widget 如何顯示輸入(有關 Text 和 Message 小窗口部件的某些示例的完整資源,請參閱 參考資料 )。字段輸入的基本小窗口部件是 Entry。它易于使用,但是如果以前曾使用過 Python 的 raw_input() 或 curses 的 .getstr() ,您將發(fā)現(xiàn)技巧略有不同。TK 的 Entry 小窗口部件不返回可分配的值。相反,它獲取自變量來填充字段對象。例如,下面的函數(shù)允許用戶指定輸入文件。
接受用戶字段輸入

            
def GetSource():
 get_window = Tkinter.Toplevel(root)
 get_window.title('Source File?')
 Tkinter.Entry(get_window, width=30,
 textvariable=source).pack()
 Tkinter.Button(get_window, text="Change",
 command=lambda: update_specs()).pack()


          

這里有幾件事要注意。我們?yōu)檫@個輸入創(chuàng)建了一個新的 Toplevel 小窗口部件和對話框,并且通過創(chuàng)建一個帶有 textvariable 自變量的 Entry 小窗口部件指定了輸入字段。但是等一下,還有件事!

textvariable 自變量沒有指定簡單的字符串變量。相反,它引用一個 StringVar 對象。在我們的示例中,從 main() 調用的 init_vars() 函數(shù)包含三行。

            
source = Tkinter.StringVar()
source.set('txt2html.txt')


          

這創(chuàng)建了一個適用于用戶輸入的對象并為其分配了初始值。每次在與之相鏈接的 Entry 小窗口部件中進行更改時都立即修改該對象。每次在 Entry 小窗口部件中擊鍵、而不是讀取終止時,都進行 raw_input() 樣式的更改。

要想獲得戶輸入的值,我們使用 StringVar 實例的 .get() 方法。例如:

            
source_string = source.get()


          

結束語

此處所略述的技巧以及我們在完整的應用程序源代碼中使用的技巧應該足以使您開始進行 Tkinter 編程了。略微實踐之后您就會發(fā)現(xiàn)它不難掌握。有一個好處是:可以通過 Python 以外的很多語言訪問 TK 庫,因此您使用 Python 的 Tkinter 模塊學到的大多數(shù)知識可以應用到其它語言。


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 资阳市| 波密县| 芷江| 辽源市| 宝兴县| 木里| 汽车| 濮阳县| 永吉县| 准格尔旗| 定州市| 安陆市| 拜城县| 麦盖提县| 江西省| 洛川县| 峨边| 荥阳市| 寻乌县| 个旧市| 霞浦县| 石台县| 延川县| 广水市| 阿拉尔市| 勃利县| 丰都县| 神木县| 三门峡市| 湖南省| 来安县| 松江区| 寿宁县| 水富县| 钦州市| 定兴县| 宣城市| 梧州市| 高雄市| 诸城市| 鄂托克旗|