002.02 Tkinter 图形接口之文本范例
主题: 002.02 Tkinter图形接口之文本范例
建檔日期: 2019/08/26
更新日期: None
语言: Python 3.7.4, tkinter 8.6
系统: Win10 Ver. 10.0.17763 繁体中文版(TW)
002.02 Tkinter图形接口之文本范例
范例以tkinter建立程序, 供用户建立文本档案, 在过程中记录下用户输入中文字的关连性, 随后提供中文输入协助的快捷键, 对输入比较的人可以起到有效的协助. 主要用到的部件有Tk(), Frame(), Button(), Label()以及Text(), 还有按键及鼠标事件处理; 另外还有档案对话filedialog及讯息框messagebox的使用.
程序接口
'''
使用Tkinter的Text部件, 建立一个简单的文本编辑器, 主要的功能为:
[1] 系统会按用户输的中文字, 记录下用户输入的第二个中文字的使用情形, 下次
再输入这个字, 会提供前十二个最常使用的下一个字, 供用户以F1~F12按键直接输入.
[2] 用户可以读入以前的文本档案, 直接学习, 建立自己的字典
[3] 这个辅助输入的字典, 是专为个人使用, 不是一般通用的字典, 一般来说, 个人常用
的词汇大都在几百字, 对输入较慢的人, 可以起到很大的作用.
'''
from tkinter.filedialog import *
from tkinter import *
from tkinter import messagebox
def enter(event): # 鼠标进入对象, 背景改为黑色
event.widget.config(bg='black')
def leave(event): # 鼠标离间对象, 背景改为原背景色
event.widget.config(bg=gnd)
def open_new_file():
'''
开启文本文件, 格式以utf-8, utf-16, GB18030来读取
'''
# 开启档案对话框
filename = filedialog.askopenfilename(title = "选择档案",
filetypes = (("文本文件","*.txt"),("所有档案","*.*")))
new_text = None
# 开启档案, 试以utf-8, utf-16及GB18030来开启, 无法开启则颢示错误
if filename != "":
print(filename)
try:
print('utf-8')
new_f = open(filename, 'rt', encoding = 'utf-8')
new_text = new_f.read()
except UnicodeDecodeError as e:
try:
print('utf-8 Failed')
new_f = open(filename, 'rt', encoding = 'utf-16')
new_text = new_f.read()
except UnicodeDecodeError as e:
try:
print('utf-16 Failed')
new_f = open(filename, 'rt', encoding = 'GB18030')
new_text = new_f.read()
except UnicodeDecodeError as e:
print('GB18030 Failed')
pass
# 档案读入, 显示在TEXT部件中
if new_text != None:
print(new_f)
print(new_text)
main_widget.t1.delete('1.0', END)
main_widget.t1.insert(END, new_text)
main_widget.t1.edit_modified(False)
else:
messagebox.showinfo(title='档案开启错误', message='文本文件格式无法读取或档案有问题')
def save_new_file():
# 开启存档对话框
filename = filedialog.asksaveasfilename(title = "储存档案",
filetypes = (("文本文件","*.txt"),("所有档案","*.*")))
if filename != "":
if filename[-4:].lower() != '.txt':
filename = filename + '.txt'
new_f = open(filename, 'wt', encoding = decoder)
new_f.write(main_widget.t1.get('1.0',END))
new_f.close()
def end_job():
# 字典存盘, 下次可再使用
if dictionary != {}:
datafile = open(dictionary_file, 'wt', encoding=decoder)
datafile.write(str(dictionary))
datafile.close()
root.destroy()
exit()
def learn_dictionary():
# 读入的档案内容, 分析内容, 加入字典中
txt = main_widget.t1.get('1.0',END)
for i in range(len(txt))[1:]:
pre_char = txt[i-1]
new_char = txt[i]
add_dictionary(pre_char, new_char)
def cmd(i):
# 按钮处理程序
if i == 0: # 开启档案
if main_widget.t1.edit_modified():
answer = messagebox.askquestion ('开启档案',
'内容已修改, 是否舍弃, 另开新档 ?',icon = 'warning')
if answer == 'yes':
open_new_file()
else:
open_new_file()
elif i == 1: # 存入档案
save_new_file()
elif i == 2: # 学习本文中的内容
learn_dictionary()
elif i == 3: # 结束离开
if main_widget.t1.edit_modified():
answer = messagebox.askquestion ('离开编辑',
'内容已修改, 是否舍弃离开 ?',icon = 'warning')
if answer == 'yes':
end_job()
else:
end_job()
def new_button(f, string, column, row):
# 建立功能按钮
obj = Button(f, text=string, font=font, width=len(string)*2, height=1, bg=gnd,
fg='white', bd=0, activebackground=gnd, command = lambda i = column: cmd(i))
obj.bind('<Enter>', enter)
obj.bind('<Leave>', leave)
obj.pack(side=LEFT)
return obj
def new_label(f, string, column, row):
# 建立F1~F12的标签
obj = Label(f, text=string, font=font, width=len(string), height=1, bg=gnd,
fg=l_gnd, bd=0, activebackground=gnd)
obj.pack(side=LEFT)
return obj
def read_dictionary():
# 读入已有的字典, 格式为{}空字典, {'字':{'字':次数, ....}, ....}
dic_f = open(dictionary_file, 'rt', encoding = decoder)
a = dic_f.read()
dictionary = eval(a)
dic_f.close()
return dictionary
def write_dictionary():
# 字典写入档案
dic_f = open(dictionary_file, 'wt', encoding = decoder)
dic_f.write(str(dictionary))
return dictionary
def find_char(char):
# 取该字的下一个最常用字清单, 共十二个, 没有补全格空格
char_dic = dictionary[char].items()
rev_list = [[v[1], v[0]] for v in char_dic]
rev_list.sort(reverse=True)
word_list = [v[1] for v in rev_list]
if len(word_list)<12:
for i in range(12-len(word_list)):
word_list.append(' ')
else:
word_list = word_list[:12]
return word_list
def find_key(char):
# 取得对应的常用字列表, 不在字典中, 则给十二个全格空格
if char not in dictionary:
word_list = [' ' for i in range(12)]
else:
word_list = find_char(char)
return word_list
def update_char(char):
# 显示十二个常用字的内容
word_list = find_key(char)
for i in range(len(key_list)):
main_widget.key[i].config(text=word_list[i])
def add_dictionary(pre_char, new_char):
'''
检查是不是中文字 ?
是中文字, 前一个字也是中文字的话
是新字, 则加入字典
不是新字, 该字的次数加1
'''
if '\u4e00' <= pre_char <= '\u9fa5':
if '\u4e00' <= new_char <= '\u9fa5':
if pre_char in dictionary:
if new_char in dictionary[pre_char]:
dictionary[pre_char][new_char] += 1
else:
dictionary[pre_char][new_char] = 1
else:
dictionary[pre_char] = {new_char:1}
def key_action(event):
if 112<=event.keycode<=123: # 检查是不是F1~F12按键
insert_char = main_widget.key[event.keycode-112]['text']
if insert_char != ' ':
main_widget.t1.insert(INSERT,insert_char)
update_char(insert_char)
else: # 按输入字, F1~F12内容更新
char = event.widget.get("%s-1c" % INSERT, INSERT)
update_char(char)
# 检查前一字, 与现在的字, 字典更新处理
pre_char = event.widget.get("%s-2c" % INSERT, "%s-1c" % INSERT)
new_char = event.widget.get("%s-1c" % INSERT, INSERT)
add_dictionary(pre_char, new_char)
class main_window():
'''
主窗口建立显示
Frame1放四个功能键(save, write, analysis, exit)
Frame2放十二个标签(F1 ~ F12)
Frame3放一个文本再加一个垂直滚动条
'''
def __init__(self):
menu_b = []
self.f_all = Frame(root, bg=gnd, padx=pad, pady=pad)
self.f_all.pack()
self.f1 = Frame(self.f_all, bg=gnd)
self.f1.pack(side=TOP)
for i in range(len(menu)):
menu_b.append(new_button(self.f1, menu[i], i, 0))
self.f2 = Frame(self.f_all, bg=gnd)
self.f2.pack(side=TOP)
self.key=[]
for i in range(len(key_list)):
new_label(self.f2, key_list[i], i*2, 1)
self.key.append(new_button(self.f2, word_list[i], i*2, 1))
self.f3 = Frame(self.f_all, bg=gnd)
self.f3.pack(side=TOP)
self.t1 = Text(self.f3, font=font, fg='white', bg=l_gnd, width=80,
height=20, padx=pad, pady=pad)
self.t1.pack(side=LEFT, fill=Y)
self.s1 = Scrollbar(self.f3)
self.s1.pack(side=RIGHT, fill=Y)
self.s1.config(command=self.t1.yview)
self.t1.config(yscrollcommand=self.s1.set)
# 按键放开处理
self.t1.bind('<KeyRelease>', key_action)
font_size = 20
font = ('微软黑体', font_size, 'bold')
pad = 10
gnd = 'gray20'
l_gnd = 'gray40'
title = '辅助输入编辑器 V1.0'
decoder = "utf-8-sig"
key_list = ["F1 ","F2 ","F3 ","F4 ","F5 ","F6 ", "F7 ","F8 ","F9 ","F10","F11","F12"]
dictionary_file = 'dictionary.txt' # 字典文件名
menu = ('开启档案', '储存档案', '学习内容', '离开编辑')
dictionary = read_dictionary() # 读入字典
word_list = [" " for i in range(12)] # F1 ~ F12 空白内容
root = Tk()
root.title(title)
root.resizable(False, False)
main_widget = main_window() # 建立程序窗口内容
root.mainloop()
# dictionary.txt 新檔自建內容為空字典 {}
# dictionary.txt 已有的內容示範
{'中': {'文': 2, '有': 2, '运': 2, '一': 1, '避': 1, '诞': 1, '类': 1, '繁': 1, '的': 5, '出': 3, '所': 1, '集': 1, '讨': 1, '和': 1}, '文': {'维': 1, '件': 11, '本': 9, '献': 3, '单': 1, '档': 1, '语': 1, '化': 1, '字': 1}, '维': {'基': 27, '图': 1, '护': 3}, '基': {'百': 8, '金': 6, '数': 3, '教': 4, '于': 14, '本': 2, '共': 3, '语': 2, '学': 2, '社': 1, '媒': 3}, '百': {'科': 9, '上': 1}, '科': {'条': 1, '全': 1, '书': 5, '学': 9, '技': 1, '的': 1, '标': 1, '免': 1}, '条': {'目': 4, '件': 4, '款': 3}, '目': {'协': 1, '录': 2, '的': 4, '标': 1, '讨': 1, '中': 1}, '协': {'作': 1, '调': 1, '议': 5, '程': 1}, '作': {'计': 1, '系': 7, '为': 11, '简': 1, '者': 1, '变': 1, '业': 2, '用': 2, '的': 1, '是': 2, '对': 1, '配': 1}, '计': {'划': 4, '者': 1, '哲': 4, '算': 16, '的': 9, '工': 1, '任': 1, '为': 1, '师': 1, '目': 1, '时': 1, '允': 1, '有': 1, '社': 1, '框': 1, '主': 1}, '划': {'专': 1, '分': 1, '例': 1, '线': 6, '中': 1}, '专': {'页': 1, '门': 4, '业': 1}, '页': {'已': 1, '设': 2, '技': 1, '面': 4}, '已': {'建': 1, '在': 1, '决': 1, '时': 1, '经': 7, '无': 1, '正': 1}, .......... }
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: