欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

利用Tkinter制作简易的文本编辑器

程序员文章站 2022-07-14 11:54:05
...

*思路分析
1.首先是复制粘贴取消重做等功能,这些功能其实不用我 们去实现,因为tkinter 有内建的实现,我们只需要调用 一个函数即可。
2.对于打开新建保存另存为,就是考验我们读写文件的基 本功了
3.对于查找,也是增加的唯一的一个比较复杂的功能,因 为它需要再建一个窗口,至于真正的查找,不用我们把文 本内容拿出来用正则去匹配然后再定位,官方有现成的 API。
4.对于作者信息和版权信息,则就是异常简单的两个显示 信息的对话框,非常没有技术含量,就不说了。
代码思路步骤 文章结尾贴有完整代码和部分注释:
首先是创建界面以及文件菜单和编辑菜单:
利用Tkinter制作简易的文本编辑器
利用Tkinter制作简易的文本编辑器
然后是在创建一个“关于”菜单:
利用Tkinter制作简易的文本编辑器
.然后是菜单命令的实现(它包括了需要导入的文件和作 者以及版权的菜单实现):
利用Tkinter制作简易的文本编辑器

利用Tkinter制作简易的文本编辑器
最后也是类似上面的函数的实现
完整代码及注释如下:

from tkinter import *
from tkinter.messagebox import * #弹出提示框的模块
from tkinter.filedialog import * #打开文件对话框,获取文件路径的模块
import os #有关文件夹的模块

root = Tk()
root.title('Carson 文本编辑器')
filename = ''
#在主窗口放置文本
textPad = Text(root,undo = True)
textPad.pack(expand = YES,fill = BOTH)

shortcutbar = Frame(root,height = 25,bg = 'light sea green')
shortcutbar.pack(expand = NO,fill = X)
lnlabel = Label(root,width = 2,bg = 'antique white')
lnlabel.pack(side = LEFT,anchor = 'nw',fill = Y)

scroll = Scrollbar(textPad)
textPad.config(yscrollcommand = scroll.set)
scroll.config(command = textPad.yview)
scroll.pack(side = RIGHT,fill = Y)
"""创建菜单栏"""
menubar = Menu(root)

def new():
    global filename,textPad,root
    root.title('这是个还未命名的文件')
    filename = None
    #清空文本
    textPad.delete(1.0,END)


def myopen():
    #因为需要修改到全局变量的值,需要加global关键字
    global filename
    default_dir = r'D:\python' #设置默认打开路径
    #下面filename返回文件路径
    #打开文件对话框并获取文件路径保存
    filename = askopenfilename(title = u'选择文件',defaultextension = '.txt',initialdir = (os.path.expanduser(default_dir))) #tKinter模块的选择文件,后面的os函数是将其中特殊字符替换成目录
    if filename == '':
        filename=None
    else:
        root.title("Carson记事本--"+os.path.basename(filename)) #basename()是获取文件路径最后的文件名
        #delete()函数中须为n.n小数形式,代表第n行第几个下标
        textPad.delete(1.0,END)
        f = open(filename,'r')
        #向文本中显示文件中的字符串,同样,insert()中,表示从第一行第一个下标插入
        textPad.insert(1.0,f.read())
        #没有使用with,需要手动关闭
        f.close()


def save():
    global filename
    try:
        f = open(filename,'w')
        #获取文本中的字符串
        message = textPad.get(1.0,END)
        f.write(message)
        f.close()
    except:
        saveas()

def saveas():
    global filename
    #打开保存文件的文件对话框
    f = asksaveasfilename(initialfile = '未命名.txt',defaultextension = '.txt') #打开文件对话框并获取文件路径保存
    filename = f
    fh = open(f,'w')
    message = textPad.get(1.0,END)
    fh.write(message)
    fh.close()
    root.title("Carson记事本--"+os.path.basename(filename))

def undo():
    global textPad
    textPad.event_generate("<<Undo>>")

def redo():
    global textPad
    textPad.event_generate("<<Redo>>")

def cut():
    global textPad
    textPad.event_generate("<<Cut>>")

def copy():
    global textPad
    textPad.event_generate("<<Copy>>")

def paste():
    global textPad
    textPad.event_generate("<<Paste>>")

def find():
    global root
    t = Toplevel(root)
    t.title('查找')
    t.geometry("260x60+200+250")
    t.transient(root) #告诉root新建t窗口是暂时等待
    Label(t,text = '查找').grid(row = 0,column = 0,sticky = W)
    v = StringVar()
    e = Entry(t,width = 20,textvariable = v)
    e.grid(row =0,column = 1,padx = 2,pady = 2,sticky = 'we')
    e.focus_set() #焦点聚集在此输入框
    c = IntVar()
    Checkbutton(t,text = '不区分大小写',variable = c).grid(row = 1,column = 1,sticky = E)
    Button(t,text = '查找所有',command = lambda :search(v.get(),c.get(),textPad,t,e)).grid(row = 0,column = 2,sticky = 'e'+'w',padx = 2,pady =2)
    def close_search():
        textPad.tag_remove('match','1.0',END)
        t.destroy()
    t.protocol('WM_DELETE_WINDOW',close_search)

def search(needle,cssnstv,textPad,t,e):
    textPad.tag_remove('match','1.0',END)
    count = 0
    if needle:
        pos = '1.0'
        while True:
            pos = textPad.search(needle,pos,nocase = cssnstv,stopindex=END)
            if not pos:
                break
            lastpos = pos +str(len(needle))
            textPad.tag_add('match',pos,lastpos)
            count +=1
            pos = lastpos
        textPad.tag_config('match',foreground = 'yellow',background = 'green')
        e.focus_set()
        t.title(str(count)+'个匹配')

#此函数用于鼠标右键显示菜单的
def popup(event):
    global editmenu
    editmenu.tk_popup(event.x_root,event.y_root)



def select_all():
    global textPad
    #tag_add():为指定的文本添加Tags
    #tag_config():可以设置Tags的样式
    textPad.tag_add('sel','1.0','end')

def author():
    showinfo('Carson提示您','This is carson的文本编辑version1')
def copyright():
    showinfo('Carson提示您','版权信息最终解释权归Carson!')

#创建Top文件菜单及其子菜单并绑定函数
filemenu = Menu(menubar)
filemenu.add_command(label = '新建',accelerator = 'Ctrl + N',command=new)
filemenu.add_command(label = '打开',accelerator = 'Ctrl + O',command = myopen)
filemenu.add_command(label = '保存',accelerator = 'Ctrl + S',command = save)
filemenu.add_command(label = '另存为',accelerator = 'Ctrl + Shift + S',command = saveas)
menubar.add_cascade(label = '文件',menu = filemenu)
#创建Top编辑菜单及其子菜单并绑定函数,同类之间用下分割线
editmenu = Menu(menubar)
editmenu.add_command(label = '撤销',accelerator = 'Ctrl + Z',command = undo)
editmenu.add_command(label = '重做',accelerator = 'Ctrl + Y',command = redo)
editmenu.add_separator()
editmenu.add_command(label = '剪切',accelerator = 'Ctrl + X',command = cut)
editmenu.add_command(label = '复制',accelerator = 'Ctrl + C',command = copy)
editmenu.add_command(label = '粘贴',accelerator = 'Ctrl + V',command = paste)
editmenu.add_separator()
editmenu.add_command(label = '查找',accelerator = 'Ctrl + F',command = find)
editmenu.add_command(label = '全选',accelerator = 'Ctrl + A',command = select_all)
menubar.add_cascade(label = '编辑',menu = editmenu)
#创建Top关于菜单及其子菜单并绑定函数
aboutmenu = Menu(menubar)
aboutmenu.add_command(label = '作者',command = author)
aboutmenu.add_command(label = '版权',command = copyright)
menubar.add_cascade(label = '关于',menu = aboutmenu)

#将前面的菜单绑定到顶部栏
root.config(menu = menubar)

#热键绑定
textPad.bind("<Control-N>",new)
textPad.bind("<Control-n>",new)
textPad.bind("<Control-O>",myopen)
textPad.bind("<Control-o>",myopen)
textPad.bind("<Control-S>",save)
textPad.bind("<Control-s>",save)
textPad.bind("<Control-A>",select_all)
textPad.bind("<Control-a>",select_all)
textPad.bind("<Control-F>",find)
textPad.bind("<Control-f>",find)

textPad.bind("<Button-3>",popup)
root.mainloop()

暂测试无误于 2020-07-30!!
效果图:
利用Tkinter制作简易的文本编辑器