Python 的Tkinter包系列之七:好例子补充2
英汉字典(使用文本文件记录英语单词和解释)、简单的通信录(使用SQLite数据库记录人员信息)
一、tkinter编写英汉字典
先看效果图:
词典文件是一个文本文件,我这里起的名字是:CET-4.txt格式如下:
每个词占用一行,单词和解释之间用*分割, 例如:
a * art.一(个);每一(个)
abandon * vt.丢弃;放弃,抛弃
ability * n.能力;能耐,本领
able * a.有能力的;出色的
baby * n.婴儿;孩子气的人
back * ad.在后;回原处;回
background * n.背景,后景,经历
cabinet * n.橱,柜;内阁
cable * n.缆,索;电缆;电报
cafe * n.咖啡馆;小餐厅
为方便,我这里将CET-4.txt和下面的源码文件放到同一个目录(文件夹)中。
源码如下:
#tkinter编写英汉字典
import tkinter
# 读取内容并执行搜索的方法
def search(word):
# 读取字典内所有内容
file = open("CET-4.txt") #指定打开文件的编码格式 utf-8
dict_list = file.readlines()
# 遍历读取的内容,查看用户输入的英文是否存在
for dict00 in dict_list:
dict_item = dict00.split("*")
# 不区分大小写查询,查询到就输出英文和中文;strip()把字符串头和尾的空格去掉
if word.upper().strip() == dict_item[0].upper().strip():
# 把查询的内容返回并结束循环
return "%s: %s" % (dict_item[0], dict_item[1])
else:
return "您查询的单词尚未收录,敬请期待。。。\n"
# 关闭流
file.close()
def search_word():
word = entry.get().strip()
if len(word) != 0:
# 执行搜索的方法,获取搜索的结果
result = search(word)
# 把结果插入到文本显示框
txt.insert(tkinter.INSERT, result)
else:
txt.insert(tkinter.INSERT, "内容不能为空\n")
# 创建主窗口
window = tkinter.Tk()
# 添加标题
window.title("XX字典")
# 设置窗口尺寸
window.geometry("400x300")
# 内容输入块
frame_input = tkinter.Frame(window, width=300, height=30)
frame_input.place(x=50, y=10)
# 输入框
entry = tkinter.Entry(frame_input, width=30)
entry.pack(side="left")
# 按钮
btn_in = tkinter.Button(frame_input, text="查询", width=5, command=search_word)
btn_in.pack(side="right", padx=5)
# 文本显示块
frame_txt = tkinter.Frame(window, width=350, height=200)
frame_txt.place(x=20, y=40)
# 文本显示框的滚动条
scroll_bar = tkinter.Scrollbar(frame_txt)
scroll_bar.pack(side="right", fill=tkinter.Y)
# 内容显示框
txt = tkinter.Text(frame_txt, width=50, height=18)
txt.pack(side="bottom", pady=15)
# 关联滚动条和文字
txt.config(yscrollcommand=scroll_bar.set)
scroll_bar.config(command=txt.yview)
# 显示
window.mainloop()
提示:使用 open() 打开文件时,中文windows系统默认采用 GBK 编码。但当要打开的文件不是 GBK 编码格式时,运行出错,可以指定打开文件的编码格式,例如:
file = open("a.txt",encoding="utf-8")
注意, encoding 参数的值,仅限于文件以文本的形式打开,也就是说,以二进制格式打开时,不能用 encoding 参数。
二、简单的通信录
使用tkinter开发一个带界面的简单的通信录管理系统
先看效果图:
使用SQLite数据库记录人员信息。
SQLite是轻量级、基于文件的数据库管理系统。Python自带Sqlite3数据库。要用Python操作SQLite,不用下载SQLite,只要先import sqlite3后,即可操作SQLite。可参见详见https://blog.csdn.net/cnds123/article/details/106372967
首先使用SQLite工具创建SQLite数据库data.db,然后创建一个数据表addressList,最后在数据表addressList中创建字段id(INTEGER PRIMARY KEY类型)、name(TEXT类型)、sex(TEXT类型)、age(INTEGER类型)、department(TEXT类型)、telephone(TEXT类型)和qq(TEXT类型)。
下面给出源码
import sqlite3
import tkinter
import tkinter.ttk
import tkinter.messagebox
def doSql(sql):
'''用来执行SQL语句,尤其是INSERT和DELETE语句'''
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute(sql)
conn.commit()
conn.close()
#创建tkinter应用程序窗口
root = tkinter.Tk()
#设置窗口大小和位置
root.geometry('500x500+400+300')
#不允许改变窗口大小
root.resizable(False, False)
#设置窗口标题
root.title('通信录管理系统')
#在窗口上放置标签组件和用于输入姓名的文本框组件
lbName = tkinter.Label(root, text='姓名:')
lbName.place(x=10, y=10, width=40, height=20)
entryName = tkinter.Entry(root)
entryName.place(x=60, y=10, width=150, height=20)
#在窗口上放置标签组件和用于选择性别的组合框组件
lbSex = tkinter.Label(root, text='性别:')
lbSex.place(x=220, y=10, width=40, height=20)
comboSex = tkinter.ttk.Combobox(root, values=('男', '女'))
comboSex.place(x=270, y=10, width=150, height=20)
#在窗口上放置标签组件和用于输入年龄的文本框组件
lbAge = tkinter.Label(root, text='年龄:')
lbAge.place(x=10, y=50, width=40, height=20)
entryAge = tkinter.Entry(root)
entryAge.place(x=60, y=50, width=150, height=20)
#在窗口上放置标签组件和用于输入部门的文本框组件
lbDepartment = tkinter.Label(root, text='部门:')
lbDepartment.place(x=220, y=50, width=40, height=20)
entryDepartment = tkinter.Entry(root)
entryDepartment.place(x=270, y=50, width=150, height=20)
#在窗口上放置标签组件和用于输入电话号码的文本框组件
lbTelephone = tkinter.Label(root, text='电话:')
lbTelephone.place(x=10, y=90, width=40, height=20)
entryTelephone = tkinter.Entry(root)
entryTelephone.place(x=60, y=90, width=150, height=20)
#在窗口上放置标签组件和用于输入QQ号码的文本框组件
lbQQ = tkinter.Label(root, text='QQ:')
lbQQ.place(x=220, y=90, width=40, height=20)
entryQQ = tkinter.Entry(root)
entryQQ.place(x=270, y=90, width=150, height=20)
#在窗口上放置用来显示通信录信息的表格,使用Treeview组件实现
frame = tkinter.Frame(root)
frame.place(x=0, y=180, width=480, height=280)
#滚动条
scrollBar = tkinter.Scrollbar(frame)
scrollBar.pack(side=tkinter.RIGHT, fill=tkinter.Y)
#Treeview组件,分别设置6列的标题和宽度
treeAddressList = tkinter.ttk.Treeview(frame,
columns=('c1', 'c2', 'c3','c4', 'c5', 'c6'),
show="headings",
yscrollcommand = scrollBar.set)
treeAddressList.column('c1', width=70, anchor='center')
treeAddressList.column('c2', width=40, anchor='center')
treeAddressList.column('c3', width=40, anchor='center')
treeAddressList.column('c4', width=120, anchor='center')
treeAddressList.column('c5', width=100, anchor='center')
treeAddressList.column('c6', width=90, anchor='center')
treeAddressList.heading('c1', text='姓名')
treeAddressList.heading('c2', text='性别')
treeAddressList.heading('c3', text='年龄')
treeAddressList.heading('c4', text='部门')
treeAddressList.heading('c5', text='电话')
treeAddressList.heading('c6', text='QQ')
treeAddressList.pack(side=tkinter.LEFT, fill=tkinter.Y)
#Treeview组件与垂直滚动条结合
scrollBar.config(command=treeAddressList.yview)
def bindData():
'''把数据库里的通信录记录读取出来,然后在表格中显示'''
#删除表格中原来的所有行
for row in treeAddressList.get_children():
treeAddressList.delete(row)
#读取数据
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute('SELECT * FROM addressList ORDER BY id ASC')
temp = cur.fetchall()
conn.close()
#把数据插入表格
for i, item in enumerate(temp):
treeAddressList.insert('', i, values=item[1:])
#调用函数,把数据库中的记录显示到表格中
bindData()
#定义Treeview组件的左键单击事件,并绑定到Treeview组件上
#单击鼠标左键,设置变量nameToDelete的值,然后可以使用“删除”按钮来删除
nameToDelete = tkinter.StringVar()
def treeviewClick(event):
if not treeAddressList.selection():
return
item = treeAddressList.selection()[0]
nameToDelete.set(treeAddressList.item(item, 'values')[0])
treeAddressList.bind('<Button-1>', treeviewClick)
#在窗口上放置用于添加通信录的按钮,并设置按钮单击事件函数
def buttonAddClick():
#检查姓名
name = entryName.get().strip()
if name == '':
tkinter.messagebox.showerror(title='很抱歉', message='必须输入姓名')
return
#姓名不能重复
conn = sqlite3.connect('data.db')
cur = conn.cursor()
cur.execute('SELECT COUNT(id) from addressList where name="' + name + '"')
c = cur.fetchone()[0]
conn.close()
if c!=0:
tkinter.messagebox.showerror(title='很抱歉', message='姓名不能重复')
return
#获取选择的性别
sex = comboSex.get()
#检查年龄
age = entryAge.get().strip()
if not age.isdigit():
tkinter.messagebox.showerror(title='很抱歉', message='年龄必须为数字')
return
if not 1<int(age)<100:
tkinter.messagebox.showerror(title='很抱歉',
message='年龄必须在1到100之间')
return
#检查部门
department = entryDepartment.get().strip()
if department == '':
tkinter.messagebox.showerror(title='很抱歉', message='必须输入部门')
return
#检查电话号码
telephone = entryTelephone.get().strip()
if telephone=='' or (not telephone.isdigit()):
tkinter.messagebox.showerror(title='很抱歉',
message='电话号码必须是数字')
return
#检查QQ号码
qq = entryQQ.get().strip()
if qq=='' or (not qq.isdigit()):
tkinter.messagebox.showerror(title='很抱歉',
message='QQ号码必须是数字')
return
#所有输入都通过检查,插入数据库
sql = 'INSERT INTO addressList(name,sex,age,department,telephone,qq) VALUES("'
sql += name + '","' + sex + '",' + age + ',"' + department + '","'
sql += telephone + '","' + qq + '")'
doSql(sql)
#添加记录后,更新表格中的数据
bindData()
buttonAdd = tkinter.Button(root, text='添加', command=buttonAddClick)
buttonAdd.place(x=120, y=140, width=80, height=20)
#在窗口上放置用于删除通信录的按钮,并设置按钮单击事件函数
def buttonDeleteClick():
name = nameToDelete.get()
if name == '':
tkinter.messagebox.showerror(title='很抱歉', message='请选择一条记录')
return
#如果已经选择了一条通信录,执行SQL语句将其删除
sql = 'DELETE FROM addressList where name="' + name + '"'
doSql(sql)
tkinter.messagebox.showinfo('恭喜', '删除成功')
#重新设置变量为空字符串
nameToDelete.set('')
#更新表格中的数据
bindData()
buttonDelete = tkinter.Button(root, text='删除', command=buttonDeleteClick)
buttonDelete.place(x=240, y=140, width=80, height=20)
root.mainloop()