《零基礎入門學習Python》第069講:GUI的終極選擇:Tkinter6
前面我們已經學習了Tkinter 的好幾個組件。繪製單行文本我們當然知道要使用Label 組件,多行選項我們使用Listbox 組件,輸入框用Entry 組件,Button 就是按鈕,Radiobutton 和Checkbutton 分別對應單选和多選的情況,然後呢,有多個組件,我們還可以使用Frame 和LabelFrame 把它們構成一個框架,之後我們還學習了兩個會滾的組件:Scrollbar 和Scale,Scrollbar 就是滾動條,Scale 就是提供一個範圍,讓用戶在這個範圍內選擇一個確切的值。
今天我們繼續學習一個新的組件:Text組件。這個組件主要是用於顯示和處理多行文本,那麼在tkinter的所有組件中,Text 組件顯得異常強大和靈活,適用於多種任務。雖然說這個組件的主要任務是用於顯示多行文本,但是它常常被用於當做簡單的文本處理器、文本編輯器或者網頁瀏覽器來使用,例如我們的IDLE的輸入框,就是Text組價構成的。
我們舉個例子來演示一下:
運行一下:

我們可以對這個文本內容進行任意的操作。
Text 組價不僅支持插入和編輯文本,還支持插入image 對象,或者前面介紹的組件,例如說你可以插入一個按鈕

接下來插入圖片試一下:

看到這裡,你是不是覺得Text組件很強大呢?其實更牛的東西還在後頭。我們接著來:
Indexes 用法
Indexes(索引)是用來指向Text 組件中文本的位置,跟Python 的序列索引一樣,Text 組件索引也是對應實際字符之間的位置。
Tkinter 提供一系列不同的索引類型:
- "line.column"(行/列)
- "line.end"(某一行的末尾)
- "insert"
- "current"
- "end"
- user-defined marks
- user-defined tags("tag.first","tag.last")
- selection(SEL_FIRST,SEL_LAST)
- window coordinate("@x,y")
- embedded object name(window,images)
- expressions
下邊我們逐個給大家講解:
"line.column"
由於我們的Text組件是支持多行文本的,所以我們現在從一個一維空間變成了二維空間,我們就可以用行和列來定位一個位置。
"%d.%d" % (line, column)
行/列是最基礎的索引方式,它們將索引位置的行號和列號以字符串的形式表示出來(中間以"." 分隔,例如"1.0")。需要注意的是,行號以1 開始,列號則以0 開始。
指定超出現有文本的最後一行的行號,或超出一行中列數的列號都不會引發錯誤。對於這樣的指定,Tkinter 解釋為已有內容的末尾的下一個位置。
需要注意的是,使用行/列的索引方式看起來像是浮點值。其實不只像而已,你在需要指定索引的時候使用浮點值代替也是可以的:

使用index() 方法可以將所有支持的“索引”格式轉換為“行/列”格式的索引號。
"line.end"
行號加上字符串".end" 的格式表示為該行最後一個字符的位置:
"insert"
對應插入光標的位置。
"current"
對應與鼠標坐標最接近的位置。不過,如果你緊按鼠標任何一個按鈕,它會直到你鬆開它才響應。
"end"
對應Text 組件的文本緩衝區最後一個字符的下一個位置。
user-defined marks
user-defined marks是對Text組件中位置的命名。"insert"和"current"是兩個預先命名好的marks,除此之外你可以自定義marks(請參考下方【Marks用法】)。
User-defined tags
User-defined tags代表可以分配給Text組件的特殊事件綁定和風格(請參考下節課的【Tags用法】)。
你可以使用"tag.first"(使用tag的文本的第一個字符之前)和"tag.last"(使用tag的文本的最後一個字符之後)語法表示標籤的範圍。
user-defined marks是對Text組件中位置的命名。"insert"和"current"是兩個預先命名好的marks,除此之外你可以自定義marks(請參考下方【Marks用法】)。
User-defined tags
User-defined tags代表可以分配給Text組件的特殊事件綁定和風格(請參考下節課的【Tags用法】)。
你可以使用"tag.first"(使用tag的文本的第一個字符之前)和"tag.last"(使用tag的文本的最後一個字符之後)語法表示標籤的範圍。
如果查無此tag,那麼Tkinter會拋出一個TclError異常。
selection(SEL_FIRST,SEL_LAST)
selection是一個名為SEL(或"sel")的特殊tag,表示當前被選中的範圍,你可以使用SEL_FIRST到SEL_LAST來表示這個範圍。如果沒有選中的內容,那麼Tkinter會拋出一個TclError異常。
window coordinate("@x,y")
你還可以使用窗口坐標作為索引。例如在一個事件綁定中,你可以使用以下代碼找到最接近鼠標位置的字符:
selection(SEL_FIRST,SEL_LAST)
selection是一個名為SEL(或"sel")的特殊tag,表示當前被選中的範圍,你可以使用SEL_FIRST到SEL_LAST來表示這個範圍。如果沒有選中的內容,那麼Tkinter會拋出一個TclError異常。
window coordinate("@x,y")
你還可以使用窗口坐標作為索引。例如在一個事件綁定中,你可以使用以下代碼找到最接近鼠標位置的字符:
"@%d,%d" % (event.x, event.y)
embedded object name(window,images)
embedded object name用於指向在Text組件中嵌入的window和image對象。要引用一個window,只要簡單地將一個Tkinter組件實例作為索引即可。引用一個嵌入的image,只需使用相應的PhotoImage和BitmapImage對象。
expressions
expressions用於修改任何格式的索引,用字符串的形式實現修改索引的表達式。
具體表達式實現如下:
embedded object name用於指向在Text組件中嵌入的window和image對象。要引用一個window,只要簡單地將一個Tkinter組件實例作為索引即可。引用一個嵌入的image,只需使用相應的PhotoImage和BitmapImage對象。
expressions
expressions用於修改任何格式的索引,用字符串的形式實現修改索引的表達式。
具體表達式實現如下:
表達式
|
含義
|
| "+ count chars" | 1.將索引向前(->)移動count個字符 2.可以越過換行符,但不能超過END的位置 |
| "- count chars" | 1.將索引向後(<-)移動count個字符 2.可以越過換行符,但不能超過"1.0"的位置 |
| "+ count lines" | 1.將索引向前(->)移動count行 2.索引會盡量保持與移動前在同一列上,但如果移動後的那一行字符太少,將移動到該行的末尾 |
| "- count lines" | 1.將索引向後(<-)移動count行 2.索引會盡量保持與移動前在同一列上,但如果移動後的那一行字符太少,將移動到該行的末尾 |
| " linestart" | 1.將索引移動到當前索引所在行的起始位置 2.注意,使用該表達式前邊必須有一個空格隔開 |
| " lineend" | 1.將索引移動到當前索引所在行的末尾 2.注意,使用該表達式前邊必須有一個空格隔開 |
| " wordstart" | 1.將索引移動到當前索引指向的單詞的開頭 2.單詞的定義是一系列字母、數字、下劃線或任何非空白字符的組合 3.注意,使用該表達式前邊必須有一個空格隔開 |
| " wordend" | 1.將索引移動到當前索引指向的單詞的末尾 2.單詞的定義是一系列字母、數字、下劃線或任何非空白字符的組合 3.注意,使用該表達式前邊必須有一個空格隔開 |
TIPS:只要結果不產生歧義,關鍵字可以被縮寫,空格也可以省略。例如:"+ 5 chars"可以簡寫成"+5c"
在實現中,為了確保表達式為普通字符串,你可以使用str或格式化操作來創建一個表達式字符串。下邊例子演示瞭如何刪除插入光標前邊的一個字符:
在實現中,為了確保表達式為普通字符串,你可以使用str或格式化操作來創建一個表達式字符串。下邊例子演示瞭如何刪除插入光標前邊的一個字符:
Marks 用法
Marks(標記)通常是嵌入到Text 組件文本中的不可見對象。事實上Marks 是指定字符間的位置,並跟隨相應的字符一起移動。Marks 有"insert","current" 和user-defined marks(用戶自定義的Marks)。其中,"insert" 和"current" 是Tkinter 預定義的特殊Marks,它們不能夠被刪除。
"insert"用於指定當前插入光標的位置,Tkinter會在該位置繪製一個閃爍的光標(因此並不是所有的Marks都不可見)。
"current"用於指定與鼠標坐標最接近的位置。不過,如果你緊按鼠標任何一個按鈕,它會直到你鬆開它才響應。
你還可以自定義任意數量的Marks,Marks的名字是由普通字符串組成,可以是除了空白字符外的任何字符(為了避免歧義,你應該起一個有意義的名字)。使用mark_set()方法創建和移動Marks。
如果你在一個Mark標記的位置之前插入或刪除文本,那麼Mark跟著一併移動。刪除Marks你需要使用mark_unset()方法,刪除Mark周圍的文本並不會刪除Mark本身。
如果有做相關練習的,應該會被Mark的很多特性所疑惑,在準備這個內容的時候也很是迷惑,找了不知多少文檔......最後總結為下邊幾個例子講解:
例1 ,Mark事實上就是索引,用於表示位置:
"current"用於指定與鼠標坐標最接近的位置。不過,如果你緊按鼠標任何一個按鈕,它會直到你鬆開它才響應。
你還可以自定義任意數量的Marks,Marks的名字是由普通字符串組成,可以是除了空白字符外的任何字符(為了避免歧義,你應該起一個有意義的名字)。使用mark_set()方法創建和移動Marks。
如果你在一個Mark標記的位置之前插入或刪除文本,那麼Mark跟著一併移動。刪除Marks你需要使用mark_unset()方法,刪除Mark周圍的文本並不會刪除Mark本身。
如果有做相關練習的,應該會被Mark的很多特性所疑惑,在準備這個內容的時候也很是迷惑,找了不知多少文檔......最後總結為下邊幾個例子講解:
例1 ,Mark事實上就是索引,用於表示位置:

例2,如果Mark 前邊的內容髮生改變,那麼Mark 的位置也會跟著移動(說白了就是Mark 會“記住”它後邊的那貨~):

例3,如果Mark 周圍的文本被刪除了,Mark 仍然還在噢(只是它後邊的那貨被刪除了,所以它六神無主,只能初始化為"1.0"):

例4,只有mark_unset() 方法可以解除Mark 的封印:

看,其實也沒有那麼難嘛~
好,講最後一點,我們看到了,默認插入內容到Mark,是插入到它的左側(就是說插入一個字符的話,Mark向後移動了一個字符的位置) 。那能不能插入到Mark的右側呢?其實是可以的,通過mark_gravity()方法就可以實現。
例5(對比例2):

由於Text 組件的功能實在太強大,內容較多,剩下的下節課繼續講解。
0 留言:
發佈留言