思路分析

1.首先是复制粘贴取消重做等功能,这些功能其实不用我 们去实现,因为tkinter 有内建的实现,我们只需要调用 一个函数即可。

2.对于打开新建保存另存为,就是考验我们读写文件的基本功了

3.对于查找,也是增加的唯一的一个比较复杂的功能,因 为它需要再建一个窗口,至于真正的查找,不用我们把文 本内容拿出来用正则去匹配然后再定位,官方有现成的 API。


代码思路步骤

文章结尾贴有完整代码和部分注释:

首先是创建界面以及文件菜单和编辑菜单:

文本编辑器java代码怎么写 文本编辑器代码教程_python


文本编辑器java代码怎么写 文本编辑器代码教程_文件路径_02


然后是在创建一个“关于”菜单:

文本编辑器java代码怎么写 文本编辑器代码教程_文件路径_03


.然后是菜单命令的实现(它包括了需要导入的文件和作 者以及版权的菜单实现):

文本编辑器java代码怎么写 文本编辑器代码教程_文件对话框_04

文本编辑器java代码怎么写 文本编辑器代码教程_子菜单_05


最后也是类似上面的函数的实现


完整代码及注释如下:

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!!

效果图:

文本编辑器java代码怎么写 文本编辑器代码教程_文件对话框_06


The End!!创作不易,欢迎点赞/评论!!