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

若是輸入文字超過(guò)兩行將導(dǎo)致第一行數(shù)據(jù)被隱藏,若是輸入更多行將造成更多文字被隱藏,雖然可以用移動(dòng)光標(biāo)的方式重新看到第1行文字,但是對(duì)于不了解程序結(jié)構(gòu)的人而言,還是比較容易誤會(huì)文字區(qū)域的內(nèi)容,最后要注意的是放大窗口并不會(huì)放大文字區(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()
運(yùn)行結(jié)果:

Text 加上滾動(dòng)條 Scrollbar 設(shè)計(jì)
如果內(nèi)容過(guò)多,我們可以加入滾動(dòng)條的設(shè)計(jì)
例子:
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) # 滾動(dòng)條與text聯(lián)動(dòng) yscrollbar.config(command=text.yview) # text與滾動(dòng)條聯(lián)動(dòng) text.config(yscrollcommand=yscrollbar.set) str = """很多人都喜歡房子清掃過(guò)后煥然一新的感覺(jué)。同樣,理完發(fā)的感覺(jué)也十分美好,因?yàn)槎嘤嗟臇|西去除了。 兒童是快樂(lè)的,因?yàn)樗麤](méi)有過(guò)多的心事,也沒(méi)有不必要的憂慮。而成人則不同, 我們的生命中有太多的積壓物和太多想像出來(lái)的復(fù)雜以及一些擴(kuò)大了的悲痛。 而生命的難度也正在于此,你要不斷清掃和放棄一些東西,因?yàn)椤吧锾钊臇|西愈少, 就愈能發(fā)揮潛能”。記得一部戲里,一個(gè)人對(duì)主人公說(shuō):“走吧,不要回頭,做不好不要回來(lái)。 ”他的意思是讓他離開(kāi)這里,是希望不要讓過(guò)去拖累他。 """ text.insert(tkinter.END, str) root.mainloop()
運(yùn)行結(jié)果:

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

現(xiàn)在即使放大text也不會(huì)有所變化,但是我們可以通過(guò)fill和expand來(lái)設(shè)置
例子:
text.pack(fill=tkinter.BOTH, expand=True)
運(yùn)行結(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()運(yùn)行結(jié)果:

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

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

只要把前面索引為0的選項(xiàng)為空字符串,就可以了,然后設(shè)置默認(rèn)索引為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)
# 改變粗細(xì)
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()運(yùn)行結(jié)果:

size
size用于設(shè)置Text文字區(qū)域的字號(hào)
例子:
import tkinter
from tkinter.font import Font
from tkinter import ttk
# 改變字體
def familyChange(event):
f = Font(family=famliyVar.get())
text.configure(font=f)
# 改變粗細(xì)
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()運(yùn)行結(jié)果:

選取文字
Text對(duì)象的get()方法可以取得目前所選的文字,在使用Text文字區(qū)域時(shí),如果有選取文字操作發(fā)生時(shí),Text的對(duì)象會(huì)將所選文字的起始索引放在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('沒(méi)有選取文字')
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對(duì)象的get()方法可以取得目前所選的文字')
root.mainloop()運(yùn)行結(jié)果:

認(rèn)識(shí)Text 的索引
Text對(duì)象的索引并不是單一數(shù)字,而是一個(gè)字符串,索引的目的是讓Text控件處理更進(jìn)一步的文件操作,下列是常見(jiàn)的索引形式
line/column('line.column'):計(jì)數(shù)方式line是從1開(kāi)始,column從0開(kāi)始計(jì)數(shù),中間用句點(diǎn)分割INSERT:目前插入點(diǎn)的位置CURRENT:光標(biāo)目前位置相對(duì)于字符的位置END:緩沖區(qū)最后一個(gè)字符后的位置
表達(dá)式Expression:索引使用表達(dá)式
+count chars:count 是數(shù)字,例如,"+2c" 索引往后移動(dòng)兩個(gè)字符-count chars:count 是數(shù)字,例如,"-2c" 索引往前移動(dòng)兩個(gè)字符
例子:
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('沒(méi)有選取文字')運(yùn)行結(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對(duì)象的get()方法\n可以取得目前所選的文字')
root.mainloop()運(yùn)行結(jié)果:

由于鼠標(biāo)光標(biāo)一直在Print按鈕上,所以列出的CURRENT是在1.0索引位置,其實(shí)如果我們?cè)谖募恢脝螕魰r(shí),CURRENT的索引位置會(huì)變動(dòng),此時(shí)INSERT的索引位置會(huì)隨著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對(duì)象的get()方法\n') text.insert(1.2, '可以取得目前所選的文字') root.mainloop()
運(yùn)行結(jié)果:

建立書(shū)簽 Marks
在編輯文件時(shí),可以在文件特殊位置建立書(shū)簽(Marks),方便查閱,書(shū)簽是無(wú)法顯示的,但會(huì)在編輯系統(tǒng)內(nèi)被記錄,如果書(shū)簽內(nèi)容被刪除,則此書(shū)簽也將自動(dòng)被刪除,其實(shí)在tkinter內(nèi)默認(rèn)有兩個(gè)書(shū)簽,INSERT和CURRENT
書(shū)簽的相關(guān)方法
index(mark):傳回指定書(shū)簽的line和columnmark_names():傳回這個(gè)Text對(duì)象所有的書(shū)簽mark_set(mark, index):在指定的index位置設(shè)置書(shū)簽mark_unset:取消指定書(shū)簽設(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è)置書(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()運(yùn)行結(jié)果:

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

除了可以使用tag_add()自行定義標(biāo)簽外,系統(tǒng)還有一個(gè)內(nèi)建標(biāo)簽SEL,代表所選取的區(qū)間
例子:
選取文字時(shí),可以依所選的文字大小顯示所選文字
import tkinter
from tkinter.font import Font
from tkinter.ttk import *
def sizeSelected(event):
# 把當(dāng)前Combobox的值,傳遞給Font
f = Font(size=sizeVar.get())
# 添加標(biāo)簽,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è)置默認(rèn)選項(xiàng),索引為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è)置焦點(diǎn)
text.focus_set()
root.mainloop()運(yùn)行結(jié)果:

我們也可以在insert()方法的第三個(gè)參數(shù)增加標(biāo)簽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è)置焦點(diǎn)
text.focus_set()
# 將Tag a設(shè)為居中,藍(lán)色,含有下劃線
text.tag_config('a', foreground='blue', justify=tkinter.CENTER, underline=True)
root.mainloop()運(yùn)行結(jié)果:

Cut/Copy/Paste 功能
編輯文件時(shí)剪貼/復(fù)制/粘貼(Cut/Copy/Paste)是很常見(jiàn)的功能,這些功能其實(shí)已經(jīng)被內(nèi)建在tkinter中,但是為了學(xué)習(xí),我們還是得掌握基本的方法
刪除插入點(diǎn)字符:
delete(INSERT) # 刪除插入點(diǎn)字符
刪除所選的文本塊,可以使用兩個(gè)參數(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('沒(méi)有選取')
# 粘貼
def pasteJob():
try:
# 讀取剪貼板內(nèi)容
copyText = text.selection_get(selection='CLIPBOARD')
# 插入內(nèi)容
text.insert(tkinter.INSERT, copyText)
except tkinter.TclError:
print('剪貼板沒(méi)有內(nèi)容')
root = tkinter.Tk()
root.geometry('200x150')
# 名字可以隨便取,tearoff是取消分割線,分割線很丑
popupment = tkinter.Menu(root, tearoff=False)
# 在彈出菜單內(nèi)建立三個(gè)命令列表
popupment.add_command(label='Cut', command=cutJob)
popupment.add_command(label='Copy', command=copyJob)
popupment.add_command(label='Paste', command=pasteJob)
# 單擊鼠標(biāo)右鍵綁定顯示彈出菜單
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()運(yùn)行結(jié)果:

使用內(nèi)建的虛擬方法重新設(shè)計(jì)復(fù)制粘貼剪貼
# 剪貼
def cutJob():
text.event_generate('<<Cut>>')
# 復(fù)制
def copyJob():
text.event_generate('<<Copy>>')
# 粘貼
def pasteJob():
text.event_generate('<<Paste>>')只需要小改一下即可,就是辣么簡(jiǎn)單,但是簡(jiǎn)單歸簡(jiǎn)單,還是得掌握基本的方法與思路
撤銷與恢復(fù)
Text控件有一個(gè)簡(jiǎn)單撤銷(undo)和恢復(fù)(redo)的機(jī)制, 這個(gè)機(jī)制可以應(yīng)用于文字刪除(delete)和文字插入(insert)。
Text控件默認(rèn)環(huán)境下沒(méi)有開(kāi)啟這個(gè)機(jī)制的,如果要使用此功能,可以在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('先前沒(méi)有動(dòng)作')
# 恢復(fù)
def redoJob():
try:
text.edit_redo()
except tkinter.TclError:
print('先前沒(méi)有動(dòng)作')
root = tkinter.Tk()
root.geometry('200x150')
# 名字可以隨便取,tearoff是取消分割線,分割線很丑
popupment = tkinter.Menu(root, tearoff=False)
# 在彈出菜單內(nèi)建立三個(gè)命令列表
popupment.add_command(label='Cut', command=cutJob)
popupment.add_command(label='Copy', command=copyJob)
popupment.add_command(label='Paste', command=pasteJob)
# 單擊鼠標(biāo)右鍵綁定顯示彈出菜單
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一定要開(kāi)
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()運(yùn)行結(jié)果:

有點(diǎn)類似上一步和復(fù)原
第63行的undo=True一定要開(kāi),增加了這個(gè)參數(shù)后,程序的第26行就可以用text對(duì)象調(diào)用edit_undo()方法,這個(gè)方法會(huì)自動(dòng)執(zhí)行Undo動(dòng)作。程序的34行就可以用text對(duì)象調(diào)用edit_redo()方法,這個(gè)方法會(huì)自動(dòng)執(zhí)行Redo動(dòng)作
查找文字
在Text控件內(nèi)可以使用search()方法茶軸指定的字符串,這個(gè)方法會(huì)傳回找到的第一個(gè)指定字符串的索引。假設(shè)Text控件的對(duì)象是text,語(yǔ)法如下:
pos = text.search(key, startindex, endindex)
pos:傳回所找到的字符串的索引位置,如果查找sibai失敗則傳回空字符串key:所查找的字符串startindex:查找起始位置endindex:查找結(jié)束位置,如果查找到文檔最后可以使用END
例子:
import tkinter
def search():
# 刪除標(biāo)簽但不刪除標(biāo)簽定義
text.tag_remove('found', '1.0', tkinter.END)
# 設(shè)置起始值為1.0,也就是第一排第0個(gè)字符
start = 1.0
# 獲取輸入框的值
key = entry.get()
# 沒(méi)有輸入時(shí)
if len(key.strip()) == 0:
# 就當(dāng)什么都沒(méi)有發(fā)生
return -1
# 死循環(huán),因?yàn)槲覀儾檎业目赡懿恢挂粋€(gè)值,可能文本框中有多個(gè)
while True:
# 執(zhí)行查找,key是我們需要查詢的,start是起始值,END是從頭查到尾
pos = text.search(key, start, tkinter.END)
# 查不到就結(jié)束,break是退出死循環(huán)
if pos == '':
break
# 進(jìn)行到這一步說(shuō)明查到了數(shù)據(jù)
# 添加標(biāo)簽名,pos是查詢到的索引位置,后面這個(gè)我下面詳講
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')
# 定義找到的標(biāo)簽
text.tag_configure('found', background='yellow')
root.mainloop()運(yùn)行結(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)))
- 我們之前刪除了標(biāo)簽但沒(méi)有刪除屬性,也就是背景顏色,這里重新添加一下found標(biāo)簽,可以自動(dòng)得到它的屬性,然后后面的pos是我們查找到的字符串的起始值
- %s+%dc’ % (pos, len(key))):索引使用表達(dá)式,假設(shè)pos是1.2,key是like,len(key)就是4,然后這個(gè)就是1.2+4c,+4c就是索引往后移動(dòng)兩個(gè)字符,這里要注意%dc是分開(kāi)的,表達(dá)式值就是1.6了,也就是查找字符的終止值,不要想復(fù)雜了
第27行:
- 更新查找起始位置,將光標(biāo)定位在已查找字符的終止值,讓它繼續(xù)往后查找~~
存儲(chǔ)Text 控件內(nèi)容
當(dāng)使用編輯程序完成文件的編排后,下一步就是將所編排的文件存儲(chǔ)
例子
import tkinter
def save():
# 獲取全部?jī)?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)
# 建立菜單類別對(duì)象,命名為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)
# 顯示菜單對(duì)象
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()運(yùn)行結(jié)果:

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

但是這樣不太美觀,不是GUI設(shè)計(jì)方式,在GUI的設(shè)計(jì)中應(yīng)該是啟動(dòng)’另存為’,然后可以選擇將文檔存儲(chǔ)的文檔夾再輸入文件名。
在tkinter.filedialog模式中有asksaveasfilename()方法,我們可以使用此方法,讓窗口出現(xiàn)對(duì)話框,再執(zhí)行存儲(chǔ)工作
例子
import tkinter
from tkinter.filedialog import asksaveasfilename
def saveAs():
# 獲取全部?jī)?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)
# 建立菜單類別對(duì)象,命名為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)
# 顯示菜單對(duì)象
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()運(yùn)行結(jié)果:

運(yùn)行結(jié)果:正規(guī)的文字編輯程序中,需要考慮的事項(xiàng)太多了,有Save命令,可以直接使用目前文件名存儲(chǔ)文件,如果尚未存盤才出現(xiàn)另存為對(duì)話框,還有可以使用快捷鍵方式快捷保存
上述的方式,如果我們?cè)谳斎胛募臅r(shí)候沒(méi)有加后綴.txt的話,會(huì)直接幫我們保存一個(gè)無(wú)格式的文件,所以一定要加后綴,下面的一種方式可以幫我們默認(rèn)加后綴
例子:
filename = asksaveasfilename(defaultextension='.txt')
這樣我們就不要刻意去輸入后綴,前提是文件就應(yīng)該是txt文件格式~
新建文檔
在設(shè)計(jì)編輯程序時(shí),有時(shí)候想要新建文檔,這時(shí)編輯程序會(huì)將編輯去清空,以供編輯新的文檔,設(shè)計(jì)方式如下:
- 刪除Text控件內(nèi)容,參考第5行
- 將窗口標(biāo)題改為
'Untitled',參考第6行
例子:
import tkinter
from tkinter.filedialog import asksaveasfilename
def newFile():
text.delete('1.0', tkinter.END)
root.title('Untitled')
def saveAs():
# 獲取全部?jī)?nèi)容
global filename
textContext = text.get('1.0', tkinter.END)
# 開(kāi)啟另存為對(duì)話框,默認(rèn)所存的文件格式是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)
# 建立菜單類別對(duì)象,命名為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)
# 顯示菜單對(duì)象
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()運(yùn)行結(jié)果:

打開(kāi)文檔
在tkinter.filedialog模塊中有askopenfilename()方法,可以使用此方法,讓窗口出現(xiàn)對(duì)話框,再執(zhí)行選擇所要打開(kāi)的文檔
filename = askopenfilename()
上述程序可以傳回所存盤文檔的路徑(含文件夾),然后可以使用open方法打開(kāi)文檔,最后將所打開(kāi)的文檔插入Text控件。步驟如下
- 在打開(kāi)對(duì)話框中選擇欲打開(kāi)的文檔,參考第13行
- 使用open File()方法打開(kāi)文檔,參考第21行
- 使用read()方法讀取文檔內(nèi)容,參考第23行
- 刪除Text控件內(nèi)容,參考第25行
- 將所讀取的文檔內(nèi)容插入Text控件,參考第27行
- 更改窗口標(biāo)題名稱,參考第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
# 讀取打開(kāi)的文檔
filename = askopenfilename()
# 如果沒(méi)有選擇文檔
if filename == '':
# 就當(dāng)什么都沒(méi)有發(fā)生
return
# 打開(kāi)文檔
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)
# 改標(biāo)題
root.title(filename)
def saveAs():
# 獲取全部?jī)?nèi)容
global filename
textContext = text.get('1.0', tkinter.END)
# 開(kāi)啟另存為對(duì)話框,默認(rèn)所存的文件格式是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)
# 建立菜單類別對(duì)象,命名為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)
# 顯示菜單對(duì)象
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()運(yùn)行結(jié)果:

默認(rèn)含滾動(dòng)條的ScrolledText 控件
正式的文本編輯程序應(yīng)該要設(shè)計(jì)滾動(dòng)條,我們可以采用之前的設(shè)計(jì)方式來(lái)設(shè)計(jì)滾動(dòng)條。在tkinter.scrolledtext模塊內(nèi)有ScrolledText控件,這是一個(gè)默認(rèn)含有滾動(dòng)條的Text控件,使用時(shí)可以先導(dǎo)入此模塊,執(zhí)行時(shí)就可以看到滾動(dòng)條
例子:
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
# 讀取打開(kāi)的文檔
filename = askopenfilename()
# 如果沒(méi)有選擇文檔
if filename == '':
# 就當(dāng)什么都沒(méi)有發(fā)生
return
# 打開(kāi)文檔
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)
# 改標(biāo)題
root.title(filename)
def saveAs():
# 獲取全部?jī)?nèi)容
global filename
textContext = text.get('1.0', tkinter.END)
# 開(kāi)啟另存為對(duì)話框,默認(rèn)所存的文件格式是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)
# 建立菜單類別對(duì)象,命名為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)
# 顯示菜單對(duì)象
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()運(yùn)行結(jié)果:

插入圖像
Text控件時(shí)允許插入圖像文件的,所插入的圖像文件會(huì)被視為一個(gè)字符方式進(jìn)行處理,所程璇的大小是實(shí)際圖像的大小
例子:
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()運(yùn)行結(jié)果:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python?pandas的八個(gè)生命周期總結(jié)
這篇文章主要從八個(gè)pandas的數(shù)據(jù)處理生命周期,整理匯總出pandas框架在整個(gè)數(shù)據(jù)處理過(guò)程中都是如何處理數(shù)據(jù)的,感興趣的小伙伴可以了解一下2022-10-10
python安裝pandas庫(kù)不成功原因分析及解決辦法
Pandas是python中非常常用的數(shù)據(jù)分析庫(kù),在數(shù)據(jù)分析、機(jī)器學(xué)習(xí)、深度學(xué)習(xí)等領(lǐng)域經(jīng)常被使用,下面這篇文章主要給大家介紹了關(guān)于python安裝pandas庫(kù)不成功原因分析及解決辦法的相關(guān)資料2023-11-11
Python+Pandas實(shí)現(xiàn)數(shù)據(jù)透視表
對(duì)于數(shù)據(jù)透視表,相信對(duì)于Excel比較熟悉的小伙伴都知道如何使用它。本文將利用Python Pandas實(shí)現(xiàn)數(shù)據(jù)透視表功能,感興趣的可以學(xué)習(xí)一下2022-06-06
把大數(shù)據(jù)數(shù)字口語(yǔ)化(python與js)兩種實(shí)現(xiàn)
當(dāng)出現(xiàn)萬(wàn)以上的整型數(shù)字時(shí),經(jīng)常要把它們口語(yǔ)化比較直觀。下面分享兩段代碼,python與js的2013-02-02
Python實(shí)現(xiàn)字符串逆序輸出功能示例
這篇文章主要介紹了Python實(shí)現(xiàn)字符串逆序輸出功能,結(jié)合具體實(shí)例形式分析了Python針對(duì)字符串的遍歷、翻轉(zhuǎn)、排序等相關(guān)操作技巧,需要的朋友可以參考下2017-06-06
Python 利用base64庫(kù) 解碼本地txt文本字符串
這篇文章主要介紹了Python 利用base64庫(kù) 解碼本地txt文本字符串的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-04-04

