Python之tkinter文字區(qū)域Text使用及說明
文字區(qū)域Text 的基本概念
Entry控件主要是處理單行的文字,Text控件可以視為Entry的擴充,因為它可以處理多行的輸入,另外也可以在文字中嵌入圖像或是提供格式化功能,因此實際上我們將使Text當(dāng)做簡單的文字處理軟件,甚至也可以當(dāng)做網(wǎng)頁瀏覽器使用
它的構(gòu)造方法如下:
Text(父對象, options, ...)
參數(shù):
- 第一個參數(shù):父對象,表示這個文字區(qū)域?qū)⒔⒃谀囊粋€窗口內(nèi)
- 第二個參數(shù):
options,參數(shù)如下
| 參數(shù) | 含義 |
|---|---|
| bg 或 background | 背景色彩 |
| bd 或 borderwidth | 邊界寬度默認是2像素 |
| cursor | 當(dāng)鼠標光標在文字區(qū)域上時光標形狀 |
| exportselection | 如果執(zhí)行選擇操作時,所選擇的字符串會自動輸出至剪貼板,如果想要避免可以設(shè)置exportselection=0 |
| fg 或 foreground | 字形色彩 |
| font | 字形 |
| height | 高,單位是字符高,實際高度會是字符高度而定 |
| highlightbackground | 當(dāng)文本框取得焦點時的背景顏色 |
| highlightcolor | 當(dāng)文本框取得焦點時的顏色 |
| highlightthickness | 取得焦點時的厚度默認值是1 |
| insertbackground | 插入光標的顏色默認是黑色 |
| insertborderwidth | 圍繞插入游標的3D厚度默認是0 |
| padx | Text 左/右框與文字最左/最右的間距 |
| pady | Text 上/下框與文字最上/最下的間距 |
| relief | 可由此控制文字外框默認是relief=SUNKEN |
| selectbackground | 被選取字符串的背景色彩 |
| selectborderwidth | 選取字符串時邊界厚度默認值是1 |
| selectforeground | 被選取字符串的前景色彩 |
| state | 輸入狀態(tài)默認是NORMAL,表示可以輸入,DISABLED則表示無法編輯 |
| tab | 可設(shè)置按Tab鍵,如何定位插入點 |
| width | Text的寬,單位是字符寬 |
| wrap | 可控制某行文字太長時的處理,當(dāng)某行文字太長時,可從字符做斷行默認是wrap=CHAR當(dāng)wrap=WORD時,只能從字做斷行 |
| xscrollcommand | 在X軸使用滾動條 |
| yscrollcommand | 在Y軸使用滾動條 |
文字區(qū)域Text 的基本應(yīng)用
例子:
import tkinter root = tkinter.Tk() text = tkinter.Text(root, height=2, width=15) text.pack() root.mainloop()
運行結(jié)果:

若是輸入文字超過兩行將導(dǎo)致第一行數(shù)據(jù)被隱藏,若是輸入更多行將造成更多文字被隱藏,雖然可以用移動光標的方式重新看到第1行文字,但是對于不了解程序結(jié)構(gòu)的人而言,還是比較容易誤會文字區(qū)域的內(nèi)容,最后要注意的是放大窗口并不會放大文字區(qū)域
插入文字insert()
insert() 可以將字符串插入指定的索引位置,它的使用格式如下:
insert(index, string)
index若是END或者是INSERT,表示將字符串插入文件末端位置
例子:
import tkinter root = tkinter.Tk() text = tkinter.Text(root, height=2, width=15) text.pack() text.insert(tkinter.END, 'Python\n') text.insert(tkinter.INSERT, 'Tkinter') root.mainloop()
運行結(jié)果:

Text 加上滾動條 Scrollbar 設(shè)計
如果內(nèi)容過多,我們可以加入滾動條的設(shè)計
例子:
import tkinter root = tkinter.Tk() text = tkinter.Text(root, height=4, width=30) text.pack(side=tkinter.LEFT) yscrollbar = tkinter.Scrollbar(root) yscrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y) # 滾動條與text聯(lián)動 yscrollbar.config(command=text.yview) # text與滾動條聯(lián)動 text.config(yscrollcommand=yscrollbar.set) str = """很多人都喜歡房子清掃過后煥然一新的感覺。同樣,理完發(fā)的感覺也十分美好,因為多余的東西去除了。 兒童是快樂的,因為他沒有過多的心事,也沒有不必要的憂慮。而成人則不同, 我們的生命中有太多的積壓物和太多想像出來的復(fù)雜以及一些擴大了的悲痛。 而生命的難度也正在于此,你要不斷清掃和放棄一些東西,因為“生命里填塞的東西愈少, 就愈能發(fā)揮潛能”。記得一部戲里,一個人對主人公說:“走吧,不要回頭,做不好不要回來。 ”他的意思是讓他離開這里,是希望不要讓過去拖累他。 """ text.insert(tkinter.END, str) root.mainloop()
運行結(jié)果:

加上X軸滾動條
例子:
import tkinter root = tkinter.Tk() # wrap="none" 讓文字不自動換行 text = tkinter.Text(root, height=4, width=30, wrap="none") # X軸滾動條 xscrollbar = tkinter.Scrollbar(root, orient=tkinter.HORIZONTAL) xscrollbar.pack(side=tkinter.BOTTOM, fill=tkinter.X) # Y軸滾動條 yscrollbar = tkinter.Scrollbar(root) yscrollbar.pack(side=tkinter.RIGHT, fill=tkinter.Y) # 因為Python是按順序解析的,所以如果這個放在前面的話,就優(yōu)選放置text了 text.pack() # Y軸滾動條與text聯(lián)動 yscrollbar.config(command=text.yview) # Y軸text與滾動條聯(lián)動 text.config(yscrollcommand=yscrollbar.set) # X軸滾動條與text聯(lián)動 xscrollbar.config(command=text.xview) # X軸text與滾動條聯(lián)動 text.config(xscrollcommand=xscrollbar.set) str = """很多人都喜歡房子清掃過后煥然一新的感覺。同樣,理完發(fā)的感覺也十分美好,因為多余的東西去除了。 兒童是快樂的,因為他沒有過多的心事,也沒有不必要的憂慮。而成人則不同, 我們的生命中有太多的積壓物和太多想像出來的復(fù)雜以及一些擴大了的悲痛。 而生命的難度也正在于此,你要不斷清掃和放棄一些東西,因為“生命里填塞的東西愈少, 就愈能發(fā)揮潛能”。記得一部戲里,一個人對主人公說:“走吧,不要回頭,做不好不要回來。 ”他的意思是讓他離開這里,是希望不要讓過去拖累他。 """ text.insert(tkinter.END, str) root.mainloop()
運行結(jié)果:

現(xiàn)在即使放大text也不會有所變化,但是我們可以通過fill和expand來設(shè)置
例子:
text.pack(fill=tkinter.BOTH, expand=True)
運行結(jié)果:

字形
在tkinter.font模塊中有Font方法,可以由此方法設(shè)定Font的相關(guān)參數(shù),例如,family、size、weight、slant、underline、overstrike
family
family 用于設(shè)置Text 文字區(qū)域的字形
例子:
import tkinter
from tkinter.font import Font
# 改變字體
def familyChange(event):
f = Font(family=famliyVar.get())
text.configure(font=f)
root = tkinter.Tk()
# 建立family下拉列表
famliyVar = tkinter.StringVar()
familyFamily = ('Arial', 'Times', 'Courier')
famliyVar.set(familyFamily[0])
optionMenu = tkinter.OptionMenu(root, famliyVar, *familyFamily, command=familyChange)
optionMenu.pack(pady=2)
# 建立text
text = tkinter.Text(root, height=4, width=30)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
root.mainloop()運行結(jié)果:

下拉框的下拉外觀很丑,我們可以進行優(yōu)化
import tkinter.ttk optionMenu = tkinter.ttk.OptionMenu(root, famliyVar, *familyFamily, command=familyChange)
其他的都可以不需要改變
運行結(jié)果:

現(xiàn)在看上方的GIF圖,就會發(fā)現(xiàn)一個bug,筆者不清楚這是因為不兼容還是本身就是這樣的,但是可以進行修改
例子:
修復(fù)ttk.OptionMenu組件在選擇后第一個選項消失的問題
familyFamily = ('', 'Arial', 'Times', 'Courier')
famliyVar.set(familyFamily[1])運行結(jié)果:

只要把前面索引為0的選項為空字符串,就可以了,然后設(shè)置默認索引為1
weight
weight用于設(shè)置text文字區(qū)域的字是否是粗體
例子:
import tkinter
from tkinter.font import Font
# 改變字體
def familyChange(event):
f = Font(family=famliyVar.get())
text.configure(font=f)
# 改變粗細
def weightChange(event):
f = Font(weight=weightVar.get())
text.configure(font=f)
root = tkinter.Tk()
# 建立工具欄
toolbar = tkinter.Frame(root, relief=tkinter.RAISED, borderwidth=1)
toolbar.pack(side=tkinter.TOP, fill=tkinter.X, padx=2, pady=1)
# 建立family下拉列表
famliyVar = tkinter.StringVar()
familyFamily = ('Arial', 'Times', 'Courier')
famliyVar.set(familyFamily[0])
optionFont = tkinter.OptionMenu(toolbar, famliyVar, *familyFamily, command=familyChange)
optionFont.pack(side=tkinter.LEFT, pady=2)
# 建立weight下拉列表
weightVar = tkinter.StringVar()
weightFamily = ('normal', 'bold')
weightVar.set(weightFamily[0])
optionWeight = tkinter.OptionMenu(toolbar, weightVar, *weightFamily, command=weightChange)
optionWeight.pack(side=tkinter.LEFT, pady=2)
# 建立text
text = tkinter.Text(root, height=4, width=30)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
root.mainloop()運行結(jié)果:

size
size用于設(shè)置Text文字區(qū)域的字號
例子:
import tkinter
from tkinter.font import Font
from tkinter import ttk
# 改變字體
def familyChange(event):
f = Font(family=famliyVar.get())
text.configure(font=f)
# 改變粗細
def weightChange(event):
f = Font(weight=weightVar.get())
text.configure(font=f)
# 改變大小
def sizeChange(event):
f = Font(size=sizeVar.get())
text.configure(font=f)
root = tkinter.Tk()
# 建立工具欄
toolbar = tkinter.Frame(root, relief=tkinter.RAISED, borderwidth=1)
toolbar.pack(side=tkinter.TOP, fill=tkinter.X, padx=2, pady=1)
# 建立family下拉列表
famliyVar = tkinter.StringVar()
familyFamily = ('', 'Arial', 'Times', 'Courier')
famliyVar.set(familyFamily[1])
optionFont = ttk.OptionMenu(toolbar, famliyVar, *familyFamily, command=familyChange)
optionFont.pack(side=tkinter.LEFT, pady=2)
# 建立weight下拉列表
weightVar = tkinter.StringVar()
weightFamily = ('', 'normal', 'bold')
weightVar.set(weightFamily[1])
optionWeight = ttk.OptionMenu(toolbar, weightVar, *weightFamily, command=weightChange)
optionWeight.pack(side=tkinter.LEFT, pady=2)
# 建立size組合框
sizeVar = tkinter.IntVar()
size = ttk.Combobox(toolbar, textvariable=sizeVar)
sizeFamily = [x for x in range(8, 30)]
size['value'] = sizeFamily
size.current(4)
size.bind('<<ComboboxSelected>>', sizeChange)
size.pack(side=tkinter.LEFT, pady=2)
# 建立text
text = tkinter.Text(root, height=4, width=30)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
root.mainloop()運行結(jié)果:

選取文字
Text對象的get()方法可以取得目前所選的文字,在使用Text文字區(qū)域時,如果有選取文字操作發(fā)生時,Text的對象會將所選文字的起始索引放在SEL_FIRST,結(jié)束索引放在SEL_LAST,將SEL_FIRST和SEL_LAST當(dāng)做get方法的參數(shù),就可以獲得目前所選的文字了
例子:
import tkinter
def show():
try:
textInfo = text.get(tkinter.SEL_FIRST, tkinter.SEL_LAST)
print(textInfo)
except tkinter.TclError:
print('沒有選取文字')
root = tkinter.Tk()
# 建立Button
button = tkinter.Button(root, text="Print", command=show)
button.pack(pady=3)
# 建立text
text = tkinter.Text(root, height=4, width=30)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
text.insert(tkinter.END, 'Text對象的get()方法可以取得目前所選的文字')
root.mainloop()運行結(jié)果:

認識Text 的索引
Text對象的索引并不是單一數(shù)字,而是一個字符串,索引的目的是讓Text控件處理更進一步的文件操作,下列是常見的索引形式
line/column('line.column'):計數(shù)方式line是從1開始,column從0開始計數(shù),中間用句點分割INSERT:目前插入點的位置CURRENT:光標目前位置相對于字符的位置END:緩沖區(qū)最后一個字符后的位置
表達式Expression:索引使用表達式
+count chars:count 是數(shù)字,例如,"+2c" 索引往后移動兩個字符-count chars:count 是數(shù)字,例如,"-2c" 索引往前移動兩個字符
例子:
try:
textInfo = text.get(tkinter.SEL_FIRST, tkinter.SEL_LAST)
print(textInfo)
print('start:' + text.index(tkinter.SEL_FIRST))
print('end:' + text.index(tkinter.SEL_LAST))
except tkinter.TclError:
print('沒有選取文字')運行結(jié)果:

例子:
列出INSERT、CURRENT、END的位置
import tkinter
def show():
print('INSERT :', text.index(tkinter.INSERT))
print('CURRENT :', text.index(tkinter.CURRENT))
print('END :', text.index(tkinter.END))
root = tkinter.Tk()
# 建立Button
button = tkinter.Button(root, text="Print", command=show)
button.pack(pady=3)
# 建立text
text = tkinter.Text(root, height=4, width=30)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
text.insert(tkinter.END, 'Text對象的get()方法\n可以取得目前所選的文字')
root.mainloop()運行結(jié)果:

由于鼠標光標一直在Print按鈕上,所以列出的CURRENT是在1.0索引位置,其實如果我們在文件位置單擊時,CURRENT的索引位置會變動,此時INSERT的索引位置會隨著CURRENT更改
例子:
在指定索引位置插入文字
import tkinter root = tkinter.Tk() # 建立text text = tkinter.Text(root, height=4, width=30) text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2) text.insert(tkinter.END, 'Text對象的get()方法\n') text.insert(1.2, '可以取得目前所選的文字') root.mainloop()
運行結(jié)果:

建立書簽 Marks
在編輯文件時,可以在文件特殊位置建立書簽(Marks),方便查閱,書簽是無法顯示的,但會在編輯系統(tǒng)內(nèi)被記錄,如果書簽內(nèi)容被刪除,則此書簽也將自動被刪除,其實在tkinter內(nèi)默認有兩個書簽,INSERT和CURRENT
書簽的相關(guān)方法
index(mark):傳回指定書簽的line和columnmark_names():傳回這個Text對象所有的書簽mark_set(mark, index):在指定的index位置設(shè)置書簽mark_unset:取消指定書簽設(shè)置
例子:
import tkinter
root = tkinter.Tk()
# 建立text
text = tkinter.Text(root)
# 插入內(nèi)容
for i in range(1, 10):
text.insert(tkinter.END, str(i) + ' I Like Python and Tkinter\n')
# 設(shè)置書簽
text.mark_set('markOne', 3.0)
text.mark_set('markTwo', 5.0)
print(text.get('markOne', 'markTwo'))
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
root.mainloop()運行結(jié)果:

3 I Like Python and Tkinter 4 I Like Python and Tkinter
建立標簽
標簽(Tags)是指一個區(qū)域文字,然后我們可以為這個區(qū)域取一個名字,這個名字稱為標簽,可以使用此標簽名字代表這個區(qū)域名字。
有了標簽后,我們可以針對此標簽做進一步的工作,例如,將字形、色彩等的應(yīng)用在此標簽上。
下列是常見的標簽方法
tag_add(tagname, startindex[, endindex] ···):將startindex和endindex間的文字命名為tagname標簽tag_conig(tagname, options, ···):可以為標簽執(zhí)行特定的編輯,或動作綁定tag_delete(tagname):刪除此標簽,同時移除此標簽特殊的編輯或綁定tag_remove(tagname[, startindex[, endindex]] ···):刪除標簽,但是不移除此標簽特殊的編輯或綁定
tag_conig的參數(shù):
| 參數(shù) | 含義 |
|---|---|
| background | 背景顏色 |
| borderwidth | 文字外圍厚度默認是0 |
| font | 字形 |
| foreground | 前景顏色 |
| justify | 對齊方式默認是LEFT,也可以是RIGHT或CENTER |
| oversticky | 如果是True,加上刪除線 |
| underline | 如果是True,加上下劃線 |
| wrap | 當(dāng)使用wrap模式時,可以使用NONE、CHAR或WORD |
例子:
import tkinter
root = tkinter.Tk()
# 建立text
text = tkinter.Text(root)
# 插入內(nèi)容
for i in range(1, 10):
text.insert(tkinter.END, str(i) + ' I Like Python and Tkinter\n')
# 設(shè)置書簽
text.mark_set('markOne', 3.0)
text.mark_set('markTwo', 5.0)
# 設(shè)置標簽
# 在區(qū)間markOne 與 markTwo之間設(shè)置標簽tag1
text.tag_add('tag1', 'markOne', 'markTwo')
# 為標簽添加屬性
text.tag_config('tag1', foreground='blue', background='lightyellow')
text.pack(fill=tkinter.BOTH, expand=True)
root.mainloop()運行結(jié)果:

除了可以使用tag_add()自行定義標簽外,系統(tǒng)還有一個內(nèi)建標簽SEL,代表所選取的區(qū)間
例子:
選取文字時,可以依所選的文字大小顯示所選文字
import tkinter
from tkinter.font import Font
from tkinter.ttk import *
def sizeSelected(event):
# 把當(dāng)前Combobox的值,傳遞給Font
f = Font(size=sizeVar.get())
# 添加標簽,SEL是選取的區(qū)間,然后選取的區(qū)間的font就是Combobox的值
text.tag_config(tkinter.SEL, font=f)
root = tkinter.Tk()
root.geometry('200x150')
# 建立工具欄
toolbar = tkinter.Frame(root, relief=tkinter.RAISED, borderwidth=1)
# 放在頂端,填充X軸
toolbar.pack(side=tkinter.TOP, fill=tkinter.X, padx=2, pady=1)
# 在工具欄上創(chuàng)建字體選擇combobox組合框
sizeVar = tkinter.IntVar()
size = Combobox(toolbar, textvariable=sizeVar)
# 列表推導(dǎo)式,選取Combobox的value范圍
sizeFamily = [x for x in range(8, 30)]
size['value'] = sizeFamily
# 設(shè)置默認選項,索引為4
size.current(4)
# 綁定Combobox事件,
size.bind('<<ComboboxSelected>>', sizeSelected)
size.pack()
# 建立text
text = tkinter.Text(root)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
text.insert(tkinter.END, 'I Like Event!')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
# 設(shè)置焦點
text.focus_set()
root.mainloop()運行結(jié)果:

我們也可以在insert()方法的第三個參數(shù)增加標簽tag
例子:
import tkinter
root = tkinter.Tk()
root.geometry('200x150')
# 建立text
text = tkinter.Text(root)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
text.insert(tkinter.END, 'I Like Event!\n', 'a')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
# 設(shè)置焦點
text.focus_set()
# 將Tag a設(shè)為居中,藍色,含有下劃線
text.tag_config('a', foreground='blue', justify=tkinter.CENTER, underline=True)
root.mainloop()運行結(jié)果:

Cut/Copy/Paste 功能
編輯文件時剪貼/復(fù)制/粘貼(Cut/Copy/Paste)是很常見的功能,這些功能其實已經(jīng)被內(nèi)建在tkinter中,但是為了學(xué)習(xí),我們還是得掌握基本的方法
刪除插入點字符:
delete(INSERT) # 刪除插入點字符
刪除所選的文本塊,可以使用兩個參數(shù):起始索引與結(jié)束索引
delete(SEL_FIRST, SEL_LAST) # 刪除所選文本塊 delete(startindex, endindex) # 刪除指定區(qū)間文本塊
刪除整份文件
delete(1.0, END)
例子:
import tkinter
def show(event):
popupment.post(event.x_root, event.y_root)
# 剪貼
def cutJob():
# 調(diào)用下面的copyJoy方法
copyJob()
# 刪除所選取的文字
text.delete(tkinter.SEL_FIRST, tkinter.SEL_LAST)
# 復(fù)制
def copyJob():
try:
# 清除剪貼板
text.clipboard_clear()
# 復(fù)制選取內(nèi)容
copyText = text.get(tkinter.SEL_FIRST, tkinter.SEL_LAST)
# 寫入剪貼板
text.clipboard_append(copyText)
except tkinter.TclError:
print('沒有選取')
# 粘貼
def pasteJob():
try:
# 讀取剪貼板內(nèi)容
copyText = text.selection_get(selection='CLIPBOARD')
# 插入內(nèi)容
text.insert(tkinter.INSERT, copyText)
except tkinter.TclError:
print('剪貼板沒有內(nèi)容')
root = tkinter.Tk()
root.geometry('200x150')
# 名字可以隨便取,tearoff是取消分割線,分割線很丑
popupment = tkinter.Menu(root, tearoff=False)
# 在彈出菜單內(nèi)建立三個命令列表
popupment.add_command(label='Cut', command=cutJob)
popupment.add_command(label='Copy', command=copyJob)
popupment.add_command(label='Paste', command=pasteJob)
# 單擊鼠標右鍵綁定顯示彈出菜單
root.bind('<3>', show)
# 建立text
text = tkinter.Text(root)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
root.mainloop()運行結(jié)果:

使用內(nèi)建的虛擬方法重新設(shè)計復(fù)制粘貼剪貼
# 剪貼
def cutJob():
text.event_generate('<<Cut>>')
# 復(fù)制
def copyJob():
text.event_generate('<<Copy>>')
# 粘貼
def pasteJob():
text.event_generate('<<Paste>>')只需要小改一下即可,就是辣么簡單,但是簡單歸簡單,還是得掌握基本的方法與思路
撤銷與恢復(fù)
Text控件有一個簡單撤銷(undo)和恢復(fù)(redo)的機制, 這個機制可以應(yīng)用于文字刪除(delete)和文字插入(insert)。
Text控件默認環(huán)境下沒有開啟這個機制的,如果要使用此功能,可以在Text()方法內(nèi)增加undo=True參數(shù)
例子:
import tkinter
def show(event):
popupment.post(event.x_root, event.y_root)
# 剪貼
def cutJob():
text.event_generate('<<Cut>>')
# 復(fù)制
def copyJob():
text.event_generate('<<Copy>>')
# 粘貼
def pasteJob():
text.event_generate('<<Paste>>')
# 撤銷
def undoJob():
try:
text.edit_undo()
except tkinter.TclError:
print('先前沒有動作')
# 恢復(fù)
def redoJob():
try:
text.edit_redo()
except tkinter.TclError:
print('先前沒有動作')
root = tkinter.Tk()
root.geometry('200x150')
# 名字可以隨便取,tearoff是取消分割線,分割線很丑
popupment = tkinter.Menu(root, tearoff=False)
# 在彈出菜單內(nèi)建立三個命令列表
popupment.add_command(label='Cut', command=cutJob)
popupment.add_command(label='Copy', command=copyJob)
popupment.add_command(label='Paste', command=pasteJob)
# 單擊鼠標右鍵綁定顯示彈出菜單
root.bind('<3>', show)
# 建立工具欄
toolbar = tkinter.Frame(root, relief=tkinter.RAISED, borderwidth=1)
toolbar.pack(side=tkinter.TOP, fill=tkinter.X, padx=2, pady=1)
# 在工具欄上建立undo與redo按鈕
undoButton = tkinter.Button(toolbar, text='Undo', command=undoJob)
undoButton.pack(side=tkinter.LEFT, padx=2, pady=1)
redoButton = tkinter.Button(toolbar, text='Redo', command=redoJob)
redoButton.pack(side=tkinter.LEFT, padx=2, pady=1)
# 建立text, undo一定要開
text = tkinter.Text(root, undo=True)
text.pack(fill=tkinter.BOTH, expand=True, padx=3, pady=2)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
root.mainloop()運行結(jié)果:

有點類似上一步和復(fù)原
第63行的undo=True一定要開,增加了這個參數(shù)后,程序的第26行就可以用text對象調(diào)用edit_undo()方法,這個方法會自動執(zhí)行Undo動作。程序的34行就可以用text對象調(diào)用edit_redo()方法,這個方法會自動執(zhí)行Redo動作
查找文字
在Text控件內(nèi)可以使用search()方法茶軸指定的字符串,這個方法會傳回找到的第一個指定字符串的索引。假設(shè)Text控件的對象是text,語法如下:
pos = text.search(key, startindex, endindex)
pos:傳回所找到的字符串的索引位置,如果查找sibai失敗則傳回空字符串key:所查找的字符串startindex:查找起始位置endindex:查找結(jié)束位置,如果查找到文檔最后可以使用END
例子:
import tkinter
def search():
# 刪除標簽但不刪除標簽定義
text.tag_remove('found', '1.0', tkinter.END)
# 設(shè)置起始值為1.0,也就是第一排第0個字符
start = 1.0
# 獲取輸入框的值
key = entry.get()
# 沒有輸入時
if len(key.strip()) == 0:
# 就當(dāng)什么都沒有發(fā)生
return -1
# 死循環(huán),因為我們查找的可能不止一個值,可能文本框中有多個
while True:
# 執(zhí)行查找,key是我們需要查詢的,start是起始值,END是從頭查到尾
pos = text.search(key, start, tkinter.END)
# 查不到就結(jié)束,break是退出死循環(huán)
if pos == '':
break
# 進行到這一步說明查到了數(shù)據(jù)
# 添加標簽名,pos是查詢到的索引位置,后面這個我下面詳講
text.tag_add('found', pos, '%s+%dc' % (pos, len(key)))
# 這里是更新查找起始位置
start = '%s+%dc' % (pos, len(key))
root = tkinter.Tk()
root.geometry('200x150')
root.rowconfigure(1, weight=1)
root.columnconfigure(0, weight=1)
# 輸入的文本框
entry = tkinter.Entry()
entry.grid(row=0, column=0, padx=5, pady=5, sticky=tkinter.W + tkinter.E)
# 查找按鈕
btu = tkinter.Button(root, text='find', command=search)
btu.grid(row=0, column=1, padx=5, pady=5)
# 建立text
text = tkinter.Text(root, undo=True)
text.grid(row=1, column=0, columnspan=2, padx=3, pady=5, sticky=tkinter.W + tkinter.E + tkinter.N + tkinter.S)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
# 定義找到的標簽
text.tag_configure('found', background='yellow')
root.mainloop()運行結(jié)果:

第19行:
pos = text.search(key, start, tkinter.END)- key:查找關(guān)鍵字
- start:查找起始值
- END:查找終止值
第25行:
- text.tag_add('found', pos, '%s+%dc' % (pos, len(key)))
- 我們之前刪除了標簽但沒有刪除屬性,也就是背景顏色,這里重新添加一下found標簽,可以自動得到它的屬性,然后后面的pos是我們查找到的字符串的起始值
- %s+%dc’ % (pos, len(key))):索引使用表達式,假設(shè)pos是1.2,key是like,len(key)就是4,然后這個就是1.2+4c,+4c就是索引往后移動兩個字符,這里要注意%dc是分開的,表達式值就是1.6了,也就是查找字符的終止值,不要想復(fù)雜了
第27行:
- 更新查找起始位置,將光標定位在已查找字符的終止值,讓它繼續(xù)往后查找~~
存儲Text 控件內(nèi)容
當(dāng)使用編輯程序完成文件的編排后,下一步就是將所編排的文件存儲
例子
import tkinter
def save():
# 獲取全部內(nèi)容
textContext = text.get('1.0', tkinter.END)
filename = 'new name.txt'
with open(filename, 'w') as output:
output.write(textContext)
root.title(filename)
root = tkinter.Tk()
root.title('Untitled')
root.geometry('200x150')
# 建立菜單欄
menubar = tkinter.Menu(root)
# 建立菜單類別對象,命名為file
filemenu = tkinter.Menu(menubar, tearoff=False)
menubar.add_cascade(label='File', menu=filemenu)
# 在file里面建立子菜單列表
filemenu.add_command(label='Save', command=save)
filemenu.add_command(label='Exit', command=root.destroy)
# 顯示菜單對象
root.config(menu=menubar)
# 建立text
text = tkinter.Text(root, undo=True)
text.pack(fill=tkinter.BOTH, expand=True)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
root.mainloop()運行結(jié)果:

他會直接存在當(dāng)前文件位置

但是這樣不太美觀,不是GUI設(shè)計方式,在GUI的設(shè)計中應(yīng)該是啟動’另存為’,然后可以選擇將文檔存儲的文檔夾再輸入文件名。
在tkinter.filedialog模式中有asksaveasfilename()方法,我們可以使用此方法,讓窗口出現(xiàn)對話框,再執(zhí)行存儲工作
例子
import tkinter
from tkinter.filedialog import asksaveasfilename
def saveAs():
# 獲取全部內(nèi)容
global filename
textContext = text.get('1.0', tkinter.END)
filename = asksaveasfilename()
if filename == '':
return
with open(filename, 'w') as output:
output.write(textContext)
root.title(filename)
filename = 'Untitled'
root = tkinter.Tk()
root.title(filename)
root.geometry('200x150')
# 建立菜單欄
menubar = tkinter.Menu(root)
# 建立菜單類別對象,命名為file
filemenu = tkinter.Menu(menubar, tearoff=False)
menubar.add_cascade(label='File', menu=filemenu)
# 在file里面建立子菜單列表
filemenu.add_command(label='Save As', command=saveAs)
filemenu.add_command(label='Exit', command=root.destroy)
# 顯示菜單對象
root.config(menu=menubar)
# 建立text
text = tkinter.Text(root, undo=True)
text.pack(fill=tkinter.BOTH, expand=True)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
root.mainloop()運行結(jié)果:

運行結(jié)果:正規(guī)的文字編輯程序中,需要考慮的事項太多了,有Save命令,可以直接使用目前文件名存儲文件,如果尚未存盤才出現(xiàn)另存為對話框,還有可以使用快捷鍵方式快捷保存
上述的方式,如果我們在輸入文件名的時候沒有加后綴.txt的話,會直接幫我們保存一個無格式的文件,所以一定要加后綴,下面的一種方式可以幫我們默認加后綴
例子:
filename = asksaveasfilename(defaultextension='.txt')
這樣我們就不要刻意去輸入后綴,前提是文件就應(yīng)該是txt文件格式~
新建文檔
在設(shè)計編輯程序時,有時候想要新建文檔,這時編輯程序會將編輯去清空,以供編輯新的文檔,設(shè)計方式如下:
- 刪除Text控件內(nèi)容,參考第5行
- 將窗口標題改為
'Untitled',參考第6行
例子:
import tkinter
from tkinter.filedialog import asksaveasfilename
def newFile():
text.delete('1.0', tkinter.END)
root.title('Untitled')
def saveAs():
# 獲取全部內(nèi)容
global filename
textContext = text.get('1.0', tkinter.END)
# 開啟另存為對話框,默認所存的文件格式是txt
filename = asksaveasfilename(defaultextension='.txt')
if filename == '':
return
with open(filename, 'w') as output:
output.write(textContext)
root.title(filename)
filename = 'Untitled'
root = tkinter.Tk()
root.title(filename)
root.geometry('200x150')
# 建立菜單欄
menubar = tkinter.Menu(root)
# 建立菜單類別對象,命名為file
filemenu = tkinter.Menu(menubar, tearoff=False)
menubar.add_cascade(label='File', menu=filemenu)
# 在file里面建立子菜單列表
filemenu.add_command(label='New File', command=newFile)
filemenu.add_command(label='Save As', command=saveAs)
filemenu.add_separator()
filemenu.add_command(label='Exit', command=root.destroy)
# 顯示菜單對象
root.config(menu=menubar)
# 建立text
text = tkinter.Text(root, undo=True)
text.pack(fill=tkinter.BOTH, expand=True)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
root.mainloop()運行結(jié)果:

打開文檔
在tkinter.filedialog模塊中有askopenfilename()方法,可以使用此方法,讓窗口出現(xiàn)對話框,再執(zhí)行選擇所要打開的文檔
filename = askopenfilename()
上述程序可以傳回所存盤文檔的路徑(含文件夾),然后可以使用open方法打開文檔,最后將所打開的文檔插入Text控件。步驟如下
- 在打開對話框中選擇欲打開的文檔,參考第13行
- 使用open File()方法打開文檔,參考第21行
- 使用read()方法讀取文檔內(nèi)容,參考第23行
- 刪除Text控件內(nèi)容,參考第25行
- 將所讀取的文檔內(nèi)容插入Text控件,參考第27行
- 更改窗口標題名稱,參考第29行
例子:
import tkinter
from tkinter.filedialog import asksaveasfilename
from tkinter.filedialog import askopenfilename
def newFile():
text.delete('1.0', tkinter.END)
root.title('Untitled')
def openFile():
# 改變變量屬性
global filename
# 讀取打開的文檔
filename = askopenfilename()
# 如果沒有選擇文檔
if filename == '':
# 就當(dāng)什么都沒有發(fā)生
return
# 打開文檔
with open(filename, 'r') as file:
# 讀取文檔的內(nèi)容
context = file.read()
# 刪除text控件的內(nèi)容
text.delete('1.0', tkinter.END)
# 插入所讀取的內(nèi)容
text.insert(tkinter.END, context)
# 改標題
root.title(filename)
def saveAs():
# 獲取全部內(nèi)容
global filename
textContext = text.get('1.0', tkinter.END)
# 開啟另存為對話框,默認所存的文件格式是txt
filename = asksaveasfilename(defaultextension='.txt')
if filename == '':
return
with open(filename, 'w') as output:
output.write(textContext)
root.title(filename)
filename = 'Untitled'
root = tkinter.Tk()
root.title(filename)
root.geometry('200x150')
# 建立菜單欄
menubar = tkinter.Menu(root)
# 建立菜單類別對象,命名為file
filemenu = tkinter.Menu(menubar, tearoff=False)
menubar.add_cascade(label='File', menu=filemenu)
# 在file里面建立子菜單列表
filemenu.add_command(label='New File', command=newFile)
filemenu.add_command(label='Open File', command=openFile)
filemenu.add_command(label='Save As', command=saveAs)
filemenu.add_separator()
filemenu.add_command(label='Exit', command=root.destroy)
# 顯示菜單對象
root.config(menu=menubar)
# 建立text
text = tkinter.Text(root, undo=True)
text.pack(fill=tkinter.BOTH, expand=True)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
root.mainloop()運行結(jié)果:

默認含滾動條的ScrolledText 控件
正式的文本編輯程序應(yīng)該要設(shè)計滾動條,我們可以采用之前的設(shè)計方式來設(shè)計滾動條。在tkinter.scrolledtext模塊內(nèi)有ScrolledText控件,這是一個默認含有滾動條的Text控件,使用時可以先導(dǎo)入此模塊,執(zhí)行時就可以看到滾動條
例子:
import tkinter
from tkinter.filedialog import asksaveasfilename
from tkinter.filedialog import askopenfilename
def newFile():
text.delete('1.0', tkinter.END)
root.title('Untitled')
def openFile():
# 改變變量屬性
global filename
# 讀取打開的文檔
filename = askopenfilename()
# 如果沒有選擇文檔
if filename == '':
# 就當(dāng)什么都沒有發(fā)生
return
# 打開文檔
with open(filename, 'r') as file:
# 讀取文檔的內(nèi)容
context = file.read()
# 刪除text控件的內(nèi)容
text.delete('1.0', tkinter.END)
# 插入所讀取的內(nèi)容
text.insert(tkinter.END, context)
# 改標題
root.title(filename)
def saveAs():
# 獲取全部內(nèi)容
global filename
textContext = text.get('1.0', tkinter.END)
# 開啟另存為對話框,默認所存的文件格式是txt
filename = asksaveasfilename(defaultextension='.txt')
if filename == '':
return
with open(filename, 'w') as output:
output.write(textContext)
root.title(filename)
filename = 'Untitled'
root = tkinter.Tk()
root.title(filename)
root.geometry('200x150')
# 建立菜單欄
menubar = tkinter.Menu(root)
# 建立菜單類別對象,命名為file
filemenu = tkinter.Menu(menubar, tearoff=False)
menubar.add_cascade(label='File', menu=filemenu)
# 在file里面建立子菜單列表
filemenu.add_command(label='New File', command=newFile)
filemenu.add_command(label='Open File', command=openFile)
filemenu.add_command(label='Save As', command=saveAs)
filemenu.add_separator()
filemenu.add_command(label='Exit', command=root.destroy)
# 顯示菜單對象
root.config(menu=menubar)
# 建立text
text = tkinter.Text(root, undo=True)
text.pack(fill=tkinter.BOTH, expand=True)
text.insert(tkinter.END, 'I Like Event!\n')
text.insert(tkinter.END, 'I Like Python!\n')
text.insert(tkinter.END, 'I Like Command!\n')
text.insert(tkinter.END, 'I Like Combobox!\n')
text.insert(tkinter.END, 'I Like Text!\n')
text.insert(tkinter.END, 'I Like Font!\n')
root.mainloop()運行結(jié)果:

插入圖像
Text控件時允許插入圖像文件的,所插入的圖像文件會被視為一個字符方式進行處理,所程璇的大小是實際圖像的大小
例子:
import tkinter
from PIL import Image, ImageTk
root = tkinter.Tk()
img = Image.open('coat.png')
myPng = ImageTk.PhotoImage(img)
text = tkinter.Text(root)
text.image_create(tkinter.END, image=myPng)
text.insert(tkinter.END, '\n')
text.insert(tkinter.END, '小小嬰兒上衣~')
text.pack(fill=tkinter.BOTH, expand=True)
root.mainloop()運行結(jié)果:

總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python+Pandas實現(xiàn)數(shù)據(jù)透視表
對于數(shù)據(jù)透視表,相信對于Excel比較熟悉的小伙伴都知道如何使用它。本文將利用Python Pandas實現(xiàn)數(shù)據(jù)透視表功能,感興趣的可以學(xué)習(xí)一下2022-06-06
把大數(shù)據(jù)數(shù)字口語化(python與js)兩種實現(xiàn)
當(dāng)出現(xiàn)萬以上的整型數(shù)字時,經(jīng)常要把它們口語化比較直觀。下面分享兩段代碼,python與js的2013-02-02

