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

簡(jiǎn)單介紹利用TK在Python下進(jìn)行GUI編程的教程

系統(tǒng) 1875 0

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

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

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

在開(kāi)始之前,我必須承認(rèn):我不是瘦小枯干的 TK 編程專(zhuān)家。事實(shí)上,我的大部分 TK 編程經(jīng)驗(yàn)大約從我寫(xiě)這篇文章三天前才開(kāi)始。那三天并非沒(méi)有挑戰(zhàn),但是最后我覺(jué)得很好地掌握了 Tkinter。我在這里要說(shuō)的是:TK 和 Tkinter 封裝器設(shè)計(jì)得都非常好,便于用戶(hù)操作,并且只是關(guān)于 GUI 編程最簡(jiǎn)單的介紹。

從測(cè)試應(yīng)用程序開(kāi)始

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

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

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

在進(jìn)一步討論代碼之前,讓我們看一下實(shí)際運(yùn)行中的應(yīng)用程序。

簡(jiǎn)單介紹利用TK在Python下進(jìn)行GUI編程的教程_第1張圖片

學(xué)習(xí)基本知識(shí)

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

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


          

這是一個(gè)完全有效的 Tkinter 程序(不要介意它沒(méi)有實(shí)際用處,因?yàn)樗踔敛还芾?"hello world")。該程序唯一需要做的是創(chuàng)建一些容納其根窗口的窗口小部件。這樣增強(qiáng)之后,無(wú)需程序員進(jìn)一步干涉,該程序的 root .mainloop() 方法調(diào)用就可以處理所有用戶(hù)交互。

main() 函數(shù)

現(xiàn)在,我們看一下 tk_txt2html.py 更現(xiàn)實(shí)的 main() 函數(shù)。請(qǐng)注意,我更喜歡使用 John Grayson 的 import Tkinter 語(yǔ)句,而不是 from Tkinter import (請(qǐng)參閱 參考資料 中所列的他的書(shū)籍)。這不是因?yàn)槲覔?dān)心名稱(chēng)空間的干擾( from ... import 語(yǔ)句的通常警告),而是因?yàn)槲蚁朊鞔_使用 Tkinter 類(lèi);我不想冒險(xiǎn)將它們與我自己的函數(shù)和類(lèi)相混淆)。建議您也這樣做,至少在開(kāi)始時(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()


          

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

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

應(yīng)用幾何圖形管理器

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

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

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

tk_txt2html 還偶爾使用 .grid() 。grid 幾何圖形管理器用可視的坐標(biāo)線(xiàn)覆蓋父代窗口小部件。當(dāng)窗口小部件調(diào)用 .grid(row=3, column=4) 時(shí),它請(qǐng)求其父代將它放在第三行第四列上。通過(guò)查看父代的所有子代的請(qǐng)求來(lái)計(jì)算父代的總行數(shù)和總列數(shù)。

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


菜單

Tkinter 能輕易生成菜單。雖然我們?cè)谶@里使用十分簡(jiǎn)單的示例,但是如果愿意,還可以用不同的字體、圖形、復(fù)選框和各種別致的子代窗口小部件來(lái)填充菜單。在我們的示例中,tk_txt2html 的菜單全部用我們?cè)谏厦嫠?jiàn)的行創(chuàng)建。

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

這行本身可能有些神秘。大多數(shù)必須完成的工作位于名為 *_menu() 的函數(shù)中。讓我們看一下最簡(jiǎn)單的示例。
創(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 排列在適當(dāng)?shù)奈恢谩enu 小窗口部件用 .add_command() 方法添加項(xiàng)。(請(qǐng)注意上面為 Menubutton 的目錄所作的奇怪分配。不要問(wèn)為什么,跟著我這樣做并在您自己的代碼中也這樣做即可。)


獲得用戶(hù)輸入

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

            
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)檫@個(gè)輸入創(chuàng)建了一個(gè)新的 Toplevel 小窗口部件和對(duì)話(huà)框,并且通過(guò)創(chuàng)建一個(gè)帶有 textvariable 自變量的 Entry 小窗口部件指定了輸入字段。但是等一下,還有件事!

textvariable 自變量沒(méi)有指定簡(jiǎn)單的字符串變量。相反,它引用一個(gè) StringVar 對(duì)象。在我們的示例中,從 main() 調(diào)用的 init_vars() 函數(shù)包含三行。

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


          

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

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

            
source_string = source.get()


          

結(jié)束語(yǔ)

此處所略述的技巧以及我們?cè)谕暾膽?yīng)用程序源代碼中使用的技巧應(yīng)該足以使您開(kāi)始進(jìn)行 Tkinter 編程了。略微實(shí)踐之后您就會(huì)發(fā)現(xiàn)它不難掌握。有一個(gè)好處是:可以通過(guò) Python 以外的很多語(yǔ)言訪(fǎng)問(wèn) TK 庫(kù),因此您使用 Python 的 Tkinter 模塊學(xué)到的大多數(shù)知識(shí)可以應(yīng)用到其它語(yǔ)言。


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

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

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!?。?/p>

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 渝北区| 田林县| 绵竹市| 广汉市| 乌拉特中旗| 东宁县| 木里| 呼伦贝尔市| 巴楚县| 伊金霍洛旗| 磴口县| 长顺县| 台南市| 密云县| 白玉县| 隆安县| 大田县| 桓仁| 吉木萨尔县| 且末县| 巩义市| 临海市| 尼木县| 休宁县| 师宗县| 东乌珠穆沁旗| 花垣县| 邮箱| 东宁县| 太仆寺旗| 巫山县| 罗平县| 巴南区| 项城市| 白朗县| 芜湖县| 昌图县| 且末县| 都昌县| 富锦市| 饶平县|