哔哩哔哩演示视频:我使用python自制了一个代码编辑器——CASM Editor_哔哩哔哩_bilibili
源代码:
- import idlelib.colorizer as idc
- import idlelib.percolator as idp
- import os
- import sys
- import threading
- import time
- import tkinter as T_tk
- import tkinter.filedialog as tf
- import tkinter.messagebox as tm
- import tkinter.scrolledtext as ts
- import tkinter.font as font
- import tkinter.ttk
- import re
- import ttkbootstrap as tk
-
- # version
- version = '0.8.1'
- running = 0
-
-
- class SettingFont:
- def __init__(self):
- self.__name = r"tools\cgy-tool-stg.def"
- try:
- with open(self.__name, encoding='utf-8') as a:
- self.font = a.readline().replace('\n', '')
- self.size = int(a.readline().replace('\n', ''))
- if self.size > 250 or self.size < 5:
- raise ValueError
- self.bold = a.readline().replace('\n', '')
- if self.bold == '':
- raise ValueError
-
- except (ValueError, OSError):
- self.font = 'Consolas'
- self.size = 20
- self.bold = 'normal'
- try:
- with open(self.__name, 'w', encoding='utf-8') as a:
- a.write(f'{self.font}\n{int(self.size)}\n{self.bold}')
- except OSError:
- def a(path):
- b = os.path.basename(path)
- c = len(list(b))
- return path[:-1 * c]
-
- os.mkdir(f'{a(__file__)}tools\\')
- with open(self.__name, 'w', encoding='utf-8') as a:
- a.write(f'{self.font}\n{int(self.size)}\n{self.bold}')
-
- def sf_return(self):
- return self.font, self.size, self.bold
-
- def shange(self, _font, size, bold):
- with open(self.__name, 'w', encoding='utf-8') as a:
- a.write(f'{_font}\n{size}\n{bold}')
- self.font = _font
- self.size = size
- self.bold = bold
-
- def check(self):
- try:
- with open(self.__name, 'r', encoding='utf-8') as a:
- _a = a.readline().replace('\n', '')
- if self.font == _a:
- b = int(a.readline().replace('\n', ''))
- if self.size == b:
- if b > 250 or b < 5:
- raise ValueError
- c = a.readline().replace('\n', '')
- if self.bold == c:
- if c == '':
- raise ValueError
- return False
- else:
- self.bold = c
- return True
- else:
- self.size = b
- return True
- else:
- self.font = _a
- return True
- except (ValueError, Exception):
- self.font = 'Consolas'
- self.size = 20
- self.bold = 'normal'
- try:
- with open(self.__name, 'w', encoding='utf-8') as a:
- a.write(f'{self.font}\n{int(self.size)}\n{self.bold}')
- except OSError:
- def a(path):
- _b = os.path.basename(path)
- _c = len(list(_b))
- return path[:-1 * _c]
-
- os.mkdir(f'{a(__file__)}tools\\')
- with open(self.__name, 'w', encoding='utf-8') as a:
- a.write(f'{self.font}\n{int(self.size)}\n{self.bold}')
- return True
-
-
- class SettingColor:
- def __init__(self):
- pass
-
-
- class GUI:
- def __init__(self):
- # vars
- self.a = None
- self.b = None
- self.c = None
- self.d = None
- self.p = None
- self.i = 0
- # wgts
-
- self.root = T_tk.Tk()
- self.root.title('CASM 文本编辑器')
- # Settings about fonts
- self.fs = SettingFont()
- self.font, self.size, self.bold = self.fs.sf_return()
- # Settings about colors
- self.cs = SettingColor()
- self.bg = "#ffffff"
- self.normal = '#000000'
- self.numbers = "#FFA500"
- self.comment = "#C0C0C0"
- self.keywords = "#00BFFF"
- self.builtin = "#7B68EE"
- self.string = "#FFA500"
- self.definition = "#228B22"
- self.symbol = "#FF0000"
- self.classmode = "#DA70D6"
- self.line = "#717171"
- # self.root.geometry('1500x900')
- # self.root.minsize(1500, 0)
- self.sb = tk.Scrollbar(self.root, orient=tk.HORIZONTAL)
- self.sb.pack(side=tk.BOTTOM, fill=tk.X)
- self.sb2 = tk.Scrollbar(self.root)
- self.sb2.pack(side=tk.RIGHT, fill=tk.Y)
- self.fall = tk.IntVar(self.root)
- self.text = tk.Text(self.root, undo=True, xscrollcommand=self.sb.set, yscrollcommand=self.sb2.set, wrap='none')
- self.text.config(font=(self.font, self.size, self.bold), background=self.bg, foreground=self.normal)
- self.numl = tk.Canvas(self.root, width=60, bg='white', highlightthickness=0)
- self.numl.pack(side=tk.LEFT, fill=tk.BOTH)
- self.text.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES)
- self.colorful = idc.color_config(self.text)
- self.sb.config(command=self.text.xview)
- self.menu = tk.Menu(self.root)
- self.popup = tk.Menu(self.root, tearoff=0)
- self.filemenu = tk.Menu(self.menu, tearoff=False)
- self.editmenu = tk.Menu(self.menu, tearoff=False)
- self.elsemenu = tk.Menu(self.menu, tearoff=False, selectcolor='green')
- self.saved = False
- self.running = False
- self.myrun = True
- self.installing = False
- self.name = ''
- self.lineall = 0
- self.old = 0
-
- def loadfile(self, file):
- file = '\n'.join((item.decode('gbk') for item in file)).split('\n')[0]
- self.open(name=file)
-
- def edit(self, text):
- self.text.delete(1.0, tk.END)
- self.text.insert(tk.END, text)
-
- def get(self):
- return self.text.get(1.0, tk.END).rstrip()
-
- def adds(self):
- self.fall.set(1) # 0开1关,默认关
- idc.color_config(self.text)
- self.p = idp.Percolator(self.text)
- self.text.focus_set()
- # windnd.hook_dropfiles(self.root, func=self.loadfile)
- self.check()
-
- def the_function_that_which_is_running_at_tkinter_key_press(event):
- self.redraw()
- self.see()
- self.redraw()
- if self.saved:
- self.save()
- self.character_completion(event)
-
- def the_function_that_which_is_running_at_tkinter_ctrl_v_press(*args):
- self.text.event_generate("<
>" ) - self.see()
-
- self.root.bind("
" , lambda event: the_function_that_which_is_running_at_tkinter_key_press(event)) - self.text.bind('
' , self.tab) - self.text.bind('
' , self.untab) - self.text.bind("
" , self.enter) - self.text.bind("
" , self.backspace) - self.text.bind("
" , self.redraw) - self.text.bind("
" , self.redraw) - self.text.bind("
" , self.redraw) - self.root.bind("
" , self.redraw) - self.root.bind("
" , self.redraw) - try:
- self.root.iconbitmap(r'images\lego.ico')
- except tkinter.TclError:
- pass
- font_ = font.Font(root=self.root, font=self.text['font'])
- tab_width = font_.measure(' ' * 4)
- self.text.config(tabs=(tab_width,))
- self.root.protocol("WM_DELETE_WINDOW", self.when_exit_do)
- self.text.tag_configure('Found', background='black', foreground='white', underline=True)
- self.menu.add_cascade(label='文件', menu=self.filemenu)
- self.menu.add_cascade(label='编辑', menu=self.editmenu)
- self.menu.add_cascade(label='其他', menu=self.elsemenu)
- self.filemenu.add_command(label='新建 Ctrl+n', command=self.mynew)
- self.filemenu.add_command(label='保存 Ctrl+s', command=self.save)
- self.filemenu.add_command(label='另存为 Ctrl+e', command=self.saveas)
- self.filemenu.add_command(label='打开文件 Ctrl+f', command=self.open)
- self.filemenu.add_command(label='运行 Ctrl+r', command=self.runtext)
- self.filemenu.add_command(label='退出 Ctrl+q', command=self.when_exit_do)
- self.editmenu.add_command(label='替换 Ctrl+Alt+r', command=self.replace)
- self.editmenu.add_command(label='寻找 Ctrl+Alt+f', command=self.find)
- self.editmenu.add_command(label='字数统计 Ctrl+Alt+t', command=self.count)
- self.editmenu.add_command(label='设置 Ctrl+Alt+s', command=self.changestg)
- self.elsemenu.add_command(label='快捷键 Ctrl+Alt+e', command=self.elsekey)
- self.elsemenu.add_command(label='关于 Ctrl+Alt+a',
- command=lambda: tm.showinfo('关于', '本编辑器由保定曹高远制作。原创。'))
- self.elsemenu.add_command(label='关于文件 Ctrl+Alt+f', command=self.about_file)
- self.elsemenu.add_checkbutton(label="全屏 F11", variable=self.fall, offvalue=0, onvalue=1,
- command=lambda: self._falls())
- self.root.bind('
' , lambda event: self.mynew()) - self.root.bind('
' , lambda event: self.save()) - self.root.bind('
' , lambda event: self.saveas()) - self.root.bind('
' , lambda event: self.runtext()) - self.root.bind('
' , lambda event: self.open()) - self.root.bind('
' , lambda event: self.when_exit_do()) - self.root.bind('
' , lambda event: self.replace()) - self.root.bind('
' , lambda event: self.find()) - self.root.bind('
' , lambda event: self.count()) - self.root.bind('
' , lambda event: self.changestg()) - self.root.bind('
' , lambda event: self.elsekey()) - self.root.bind('
' , lambda event: self.about_file()) - self.root.bind('
' , lambda event: tm.showinfo('关于', '本编辑器由伟大的天才曹高远制作。')) - self.root.bind('
' , lambda event: self.bigorsmall_font(event)) - self.root.bind('
' , lambda event: self.falls()) - self.popup.add_command(label='复制', command=lambda: self.text.event_generate("<
>" )) - self.popup.add_command(label='剪切', command=lambda: self.text.event_generate("<
>" )) - self.popup.add_command(label='粘贴', command=the_function_that_which_is_running_at_tkinter_ctrl_v_press)
- self.root.bind("
" , self.popup_menu) - self.root.config(menu=self.menu)
-
- def falls(self):
- a = self.fall.get()
- if a == 1:
- self.root.attributes("-fullscreen", False)
- self.fall.set(0) # 改变状态
- else:
- self.root.attributes("-fullscreen", True)
- self.fall.set(1)
-
- def _falls(self):
- a = self.fall.get()
- if a == 0:
- self.root.attributes("-fullscreen", False) # 不改变状态
- else:
- self.root.attributes("-fullscreen", True)
-
- def see(self):
- self.text.see(str(float(int(float(self.text.index('insert'))) + 2))) # 一直显示光标所在行
-
- def __update__(self, *args):
- while True:
- self.root.update()
- new = str(int(float(self.text.index('insert'))))
- if new != self.old:
- self.old = new
- self.redraw()
- try:
- if self.fs.check():
- self.font, self.size, self.bold = self.fs.sf_return()
- self.update()
- except RuntimeError:
- break
-
- def insert_get(self):
- start = tk.SEL_FIRST
- end = tk.SEL_LAST
- is_insert = True if self.text.get(start, end) != '' else False
- return is_insert, self.text.index(start), self.text.index(end)
-
- def update(self):
- self.text.config(font=(self.font, self.size, self.bold))
- self.redraw()
-
- def tab(self, *args):
- is_insert, start, end = self.insert_get()
- if not is_insert:
- self.text.insert('insert', ' ')
- else:
- start = int(float(start))
- end = int(float(end))
- for i in range(start, end + 1):
- self.text.insert(str(float(i)), ' ')
- return 'break'
-
- def untab(self, *args):
- is_insert, start, end = self.insert_get()
- if not is_insert:
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 4)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- if self.text.get(all_insert, 'insert') == ' ':
- self.text.delete(all_insert, 'insert')
- else:
- start = self.text.index(start)
- end = self.text.index(end)
- for i in range(int(float(start)), int(float(end)) + 1):
- last = str(int(''.join(list(self.text.index(str(float(i))))[
- (-1 * (len(os.path.splitext(self.text.index(str(float(i))))[-1]) - 1)):])) + 4)
- all_insert = ''.join(list(self.text.index(str(float(i))))[
- :(-1 * (len(os.path.splitext(self.text.index(str(float(i))))[-1]) - 1))]) + last
- if self.text.get(str(float(i)), all_insert) == ' ':
- self.text.delete(str(float(i)), all_insert)
- return 'break'
-
- def popup_menu(self, event):
- self.popup.post(event.x_root, event.y_root) # 弹出右键菜单
-
- def mynew(self):
- GUI().run()
-
- def redraw(self, *args):
- try:
- global linenum
- self.numl.delete("all")
- i = self.text.index("@0,0")
- while True:
- dline = self.text.dlineinfo(i)
- if dline is None:
- break
- y = dline[1]
- linenum = str(i).split(".")[0]
- self.numl.create_text(2, y, anchor="nw", text=linenum, fill=self.line,
- font=(self.font, self.size, self.bold))
- i = self.text.index("%s+1line" % i)
-
- _font = font.Font(root=self.root, family=self.font, size=self.size)
- w = _font.measure('0')
- self.numl.config(width=len(linenum) * w + 5)
- self.lineall = linenum
- except RuntimeError:
- pass
-
- def save(self):
- if self.name == '':
- self.name = tf.asksaveasfilename(initialfile='main.casm', defaultextension='.casm',
- filetypes=(('CASM文件', ('*.casm', '*.txt')), ('所有文件', '*.*')))
- if self.name == '':
- return
- try:
- with open(self.name, 'w', encoding='utf-8') as casm:
- casm.write(self.text.get(1.0, tk.END)[:-1])
- except:
- self.name = ''
- else:
- self.saved = True
- self.root.title(self.name)
- else:
- try:
- with open(self.name, 'w', encoding='utf-8') as casm:
- casm.write(self.text.get(1.0, tk.END)[:-1])
- except OSError:
- pass
-
- def saveas(self):
- if self.saved:
- if self.running:
- tm.showerror('文本编辑器', '文件正在运行,请先关闭。')
- return
- self.name = tf.asksaveasfilename(initialfile='main.casm', defaultextension='.casm',
- filetypes=(('CASM文件', ('*.casm', '*.txt')), ('所有文件', '*.*')))
- if self.name == '':
- return
- try:
- with open(self.name, 'w', encoding='utf-8') as casm:
- casm.write(self.text.get(1.0, tk.END)[:-1])
- except:
- self.name = ''
- else:
- self.saved = True
- self.root.title(self.name)
-
- def highins(self, text: str):
- self.text.insert(tk.END, text)
-
- def open(self, name=''):
- if self.running:
- tm.showerror('文本编辑器', '文件正在运行,请先关闭。')
- return
- if name == '':
- if self.name == '':
- self.name = tf.askopenfilename(
- filetypes=(("CASM文件", ("*.casm", '*.txt')), ("所有文件", "*.*")))
- if self.name == '':
- return
- try:
- with open(self.name, encoding='utf-8') as casm:
- self.text.delete(1.0, tk.END)
- self.highins(casm.read())
- except UnicodeError:
- self.saved = False
- self.redraw()
- self.name = ''
- self.root.title('CASM 文本编辑器')
- tm.showerror('文本编辑器', '我们只支持编码为utf-8文件。')
- except PermissionError:
- self.saved = False
- self.redraw()
- self.name = ''
- self.root.title('CASM 文本编辑器')
- tm.showerror('Error', '权限不足,访问被拒绝')
- else:
-
- self.check()
- self.redraw()
- self.saved = True
- self.root.title(self.name)
- self.text.edit_reset() # 重置文本框的撤销功能
- else:
- a = tm.askokcancel(self.name, '你已打开了一个文件,要把它关闭并保存在打开新文件吗?')
- if a:
- self.name = tf.askopenfilename(
- filetypes=(("CASM文件", ("*.casm", '*.txt')), ("所有文件", "*.*")))
- if self.name == '':
- return
- try:
- with open(self.name, encoding='utf-8') as casm:
- self.text.delete(1.0, tk.END)
- self.highins(casm.read())
- except UnicodeError:
- self.saved = False
- self.redraw()
- self.name = ''
- self.root.title('CASM 文本编辑器')
- tm.showerror('文本编辑器', '我们只支持编码为utf-8文件。')
- except PermissionError:
- self.saved = False
- self.redraw()
- self.name = ''
- self.root.title('CASM 文本编辑器')
- tm.showerror('Error', '权限不足,访问被拒绝')
- else:
- self.check()
- self.redraw()
- self.saved = True
- self.root.title(self.name)
- self.text.edit_reset()
- else:
- if self.name == '':
- try:
- with open(name, encoding='utf-8') as casm:
- self.text.delete(1.0, tk.END)
- self.highins(casm.read())
- except UnicodeError:
- self.saved = False
- self.redraw()
- self.root.title('CASM 文本编辑器')
- tm.showerror('文本编辑器', '我们只支持编码为utf-8文件。')
- except PermissionError:
- self.saved = False
- self.redraw()
- self.root.title('CASM 文本编辑器')
- tm.showerror('Error', '权限不足,访问被拒绝')
- except OSError:
- self.saved = False
- self.redraw()
- self.text.delete(1.0, tk.END)
- self.text.insert(tk.END, name)
- else:
- self.name = name
- self.check()
- self.redraw()
- self.saved = True
- self.root.title(self.name)
- self.text.edit_reset()
- else:
- a = tm.askokcancel(self.name, '你已打开了一个文件,要把它关闭并保存在打开新文件吗?')
- if a:
- try:
- with open(name, encoding='utf-8') as casm:
- self.text.delete(1.0, tk.END)
- self.highins(casm.read())
- except UnicodeError:
- self.saved = False
- self.redraw()
- self.root.title('CASM 文本编辑器')
- tm.showerror('文本编辑器', '我们只支持编码为utf-8文件。')
- except PermissionError:
- self.saved = False
- self.redraw()
- self.root.title('CASM 文本编辑器')
- tm.showerror('Error', '权限不足,访问被拒绝')
- except OSError:
- self.saved = False
- self.redraw()
- self.text.delete(1.0, tk.END)
- self.text.insert(tk.END, name)
- else:
- self.name = name
- self.check()
- self.redraw()
- self.saved = True
- self.root.title(self.name)
- self.text.edit_reset()
-
- def make_pat(self):
- def _any(name, alternates):
- return "(?P<%s>" % name + "|".join(alternates) + ")"
-
- kwlist = ["FUNC", "VAR", "IFE", "IFB", "IFS", "GOTO", "IF", "RET"]
- kw = r"\b" + _any("KEYWORD", kwlist) + r"\b"
- builtinlist = ["TYPE", "PUSH", "OUT", "ENDL", "PUSHCOMMENT", "POP", "ADD", "SUB", "MUL", "DIV", "MOD", "IN",
- "GETVAR", "PUSHVAR", "EXIT", "RAND", "NOT", "CLEAR", "STR", "INT", "BOOL", "DOUBLE", "FLOAT",
- "CHAR"]
- # builtin = r"([^.'\"\\#]\b|^)" + _any("BUILTIN", builtinlist) + r"\b"
- builtin = r"\b" + _any("BUILTIN", builtinlist) + r"\b"
- comment = _any("COMMENT", [r";[^\n]*"])
- number = _any("NUM", [r"\b[0-9]+(?![0-9]+)\b"])
- prog = re.compile("|".join([
- builtin, comment, kw, number,
- _any("SYNC", [r"\n"]),
- ]),
- re.DOTALL | re.MULTILINE)
- return prog
-
- def check(self):
- if (os.path.splitext(self.name)[-1] in ['.casm', '.txt']) or self.name == '':
- try:
- self.p.removefilter(self.d)
- except AssertionError:
- pass
- self.d = idc.ColorDelegator()
- self.d.prog = self.make_pat()
- self.d.tagdefs['COMMENT'] = {'foreground': self.comment}
- self.d.tagdefs['KEYWORD'] = {'foreground': self.keywords}
- self.d.tagdefs['BUILTIN'] = {'foreground': self.builtin}
- self.d.tagdefs['NUM'] = {'foreground': self.numbers}
- try:
- self.p.insertfilter(self.d)
- except AssertionError:
- pass
- else:
- try:
- self.p.removefilter(self.d)
- except AssertionError:
- pass
- self.d = idc.ColorDelegator()
- self.d.prog = self.make_pat()
- self.d.tagdefs['COMMENT'] = {'foreground': self.normal}
- self.d.tagdefs['KEYWORD'] = {'foreground': self.normal}
- self.d.tagdefs['BUILTIN'] = {'foreground': self.normal}
- self.d.tagdefs['NUM'] = {'foreground': self.normal}
- try:
- self.p.insertfilter(self.d)
- except AssertionError:
- pass
-
- def runtext(self):
- if self.saved:
- if not self.running:
- self.save()
- print(self.name[-5:])
- if self.name[-5:] == '.casm':
- path = self.name.split('/')
- path = '\\'.join(path[:-1])
- cmd = f'{self.name[:2]} & cd \"{path}\\\" & casm.exe \"{self.name}\" & pause' # 加‘&’连续执行cmd命令
- elif self.name[-4:] == '.txt':
- path = self.name.split('/')
- path = '\\'.join(path[:-1])
- cmd = f'{self.name[:2]} & cd \"{path}\\\" & casm.exe \"{self.name}\"'
- else:
- cmd = ''
-
- def aa():
- self.running = True
- print("cmd:",cmd)
- os.system(cmd)
- self.running = False
-
- self.a = threading.Thread(target=aa)
- self.a.start()
- else:
- tm.showerror(self.name, '文件已运行')
- else:
- self.mycallsave()
-
- def mycallsave(self):
- tm.showinfo('文本编辑器', '你没有保存这个文件,请先保存。')
- self.save()
-
- def run(self):
- global running
- running += 1
- self.adds()
- self.redraw()
- self.falls()
- while True:
- self.__update__()
-
- def enter(self, *args):
- self.i = 0
- a = self.text.index('insert')
- aa = int(float(a))
- b = self.text.get(float(aa), a).replace('\n', '')
- c = b
- if b[0:5] == 'FUNC ':
- i = 0
- while True:
- if b[:4] == ' ':
- b = b[4:]
- i += 1
- else:
- break
- self.i = i + 1
- else:
- i = 0
- while True:
- if b[:4] == ' ':
- b = b[4:]
- i += 1
- else:
- break
- self.i = i
- try:
- a = c.strip().split()[0]
- except IndexError:
- a = ''
- self.text.insert('insert', '\n')
- for j in range(self.i):
- self.text.insert('insert', ' ')
- self.redraw()
- self.see()
- return 'break'
-
- def backspace(self, *args):
- _dict = {'(': ')', '{': '}', '[': ']', '"': '"', "'": "'"}
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 1)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- a = self.text.get(all_insert, 'insert')
- if a in ['(', '{', '[', '"', "'"]:
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) + 1)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- b = self.text.get('insert', all_insert)
- if b == _dict[a]: # 符合条件,删除2个
- last1 = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 1)
- all_insert1 = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last1
- last2 = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) + 1)
- all_insert2 = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last2
- self.text.delete(all_insert1, all_insert2)
- return 'break'
- else:
- last1 = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 4)
- all_insert1 = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last1
- if self.text.get(all_insert1, 'insert') == ' ':
- self.text.delete(all_insert1, 'insert')
- return 'break'
-
- def character_completion(self, event: T_tk.Event): # 字符补全(对【(】、【[】、【{】等进行自动补全)
- a = event.keysym
- if a == 'parenleft': # (
- self.text.insert("insert", ')')
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 1)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- self.text.mark_set('insert', all_insert)
- elif a == 'braceleft': # {
- self.text.insert("insert", '}')
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 1)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- self.text.mark_set('insert', all_insert)
- elif a == 'bracketleft': # [
- self.text.insert("insert", ']')
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 1)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- self.text.mark_set('insert', all_insert)
- elif a == 'quotedbl':
- self.text.insert("insert", '"')
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 1)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- self.text.mark_set('insert', all_insert)
- elif a == "apostrophe":
- self.text.insert("insert", "'")
- last = str(int(''.join(list(self.text.index('insert'))[
- (-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1)):])) - 1)
- all_insert = ''.join(list(self.text.index('insert'))[
- :(-1 * (len(os.path.splitext(self.text.index('insert'))[-1]) - 1))]) + last
- self.text.mark_set('insert', all_insert)
-
- '''EDIT TOOLS'''
-
- def __replace(self, ta, tb, num):
- if ta and tb and num:
- num = int(num)
- if num == -1:
- a = self.get()
- a = a.replace(ta, tb)
- self.edit(a)
- elif num >= 0:
- pass
- else:
- a = self.get()
- a = a.replace(ta, tb, num)
- self.edit(a)
- else:
- tm.showerror('文本编辑器', '文本框不可留空!')
-
- def replace(self):
- if self.name != '':
- self.save()
- root = tk.Toplevel()
- root.title('替换')
- root.resizable(False, False)
- try:
- root.iconbitmap(r'images\lego.ico')
- except tkinter.TclError:
- pass
- label = tk.Label(root, text=u'原始内容:')
- label.grid(padx=10, pady=10, row=0, column=0)
- entry = tk.Entry(root)
- entry.grid(padx=10, pady=10, row=0, column=1)
- label2 = tk.Label(root, text=u'替换为:')
- label2.grid(padx=10, pady=10, row=1, column=0)
- entry2 = tk.Entry(root)
- entry2.grid(padx=10, pady=10, row=1, column=1)
- label3 = tk.Label(root, text='次数(-1为全部替换)')
- label3.grid(padx=10, pady=10, row=2, column=0)
- entry3 = tk.Entry(root)
- entry3.grid(padx=10, pady=10, row=2, column=1)
- btn = tk.Button(root, text='替换!',
- command=lambda: self.__replace(entry.get(), entry2.get(), entry3.get()))
- btn.grid(padx=10, pady=10, row=3, column=0)
- root.mainloop()
- else:
- self.mycallsave()
-
- def __find(self, msg: str):
- if self.name:
- if msg:
- i = 0
- self.text.tag_remove('Found', '1.0', tk.END)
- start = '1.0'
- if len(msg.rstrip()) == 0:
- return 0
- while True:
- pos = self.text.search(msg, start, tk.END)
- if pos == '':
- break
- i += 1
- self.text.tag_add('Found', pos, '%s+%dc' % (pos, len(msg)))
- start = '%s+%dc' % (pos, len(msg))
- return i
- else:
- tm.showerror('文本编辑器', '文本框不可留空!')
- else:
- self.mycallsave()
-
- def delatefind(self):
- self.text.tag_remove('Found', '1.0', tk.END)
-
- def runfind(self, msg):
- a = self.__find(msg)
- tm.showinfo(self.name, f'共找到"{msg}"{a}个。')
-
- def find(self):
- if self.name != '':
- self.save()
- root = tk.Toplevel()
- root.title('查找')
- try:
- root.iconbitmap(r'images\lego.ico')
- except tkinter.TclError:
- pass
- root.resizable(False, False)
- entry = tk.Entry(root)
- entry.grid(row=1, column=0, pady=10, padx=10)
- btn1 = tk.Button(root, text='寻找', command=lambda: self.runfind(entry.get().rstrip()))
- btn1.grid(row=1, column=1, padx=10, pady=10)
- btn2 = tk.Button(root, text='清空', command=self.delatefind)
- btn2.grid(row=1, column=2, padx=10, pady=10)
- root.mainloop()
-
- def count(self):
- '''字数统计'''
- if self.name != '':
- self.save()
- a = self.get()
- a = len(list(a))
- tm.showinfo('字数统计', f'文件{self.name}有字符{a}个')
- else:
- self.mycallsave()
-
- def bigorsmall_font(self, event):
- if event.delta > 0:
- if self.size < 250:
- self.size += 1
- self.text.config(font=(self.font, self.size, self.bold))
- self.redraw()
- font_ = font.Font(root=self.root, font=self.text['font'])
- tab_width = font_.measure(' ' * 4)
- self.text.config(tabs=tab_width)
- else:
- tm.showerror('CASM编辑器', '字体过大')
- else:
- if self.size > 5:
- self.size -= 1
- self.text.config(font=(self.font, self.size, self.bold))
- self.redraw()
- font_ = font.Font(root=self.root, font=self.text['font'])
- tab_width = font_.measure(' ' * 4)
- self.text.config(tabs=tab_width)
- else:
- tm.showerror('CASM编辑器', '字体过小')
- self.fs.shange(self.font, int(self.size), self.bold)
-
- def changestg(self):
- root = tk.Toplevel()
- root.title('设置')
- root.geometry('300x250')
- try:
- root.iconbitmap(r'images\lego.ico')
- except tkinter.TclError:
- pass
- root.resizable(False, False)
- notepad = tkinter.ttk.Notebook(root)
- fr1 = tk.Frame(root)
- notepad.add(fr1, text='设置')
- var = tk.StringVar(root)
- var3 = tk.BooleanVar(root)
- var3.set(True if self.bold == "bold" else False)
- fontsfam = sorted([i for i in font.families(root) if not i.startswith("@")], reverse=True)
- fontsfam = tuple(fontsfam)
-
- var.set(self.font)
- var2 = tk.IntVar(root)
- var2.set(self.size)
- label = tk.Label(fr1, text=u'字体:')
- label.grid(row=0, column=0, padx=10, pady=10)
- cb = tkinter.ttk.Combobox(fr1, textvariable=var, values=fontsfam, width=30,
- state='readonly') # state='readonly':将下拉列表设置成为只读模式
- cb.grid(row=0, column=1, pady=10, padx=10)
- label2 = tk.Label(fr1, text='大小')
- label2.grid(row=1, column=0, pady=10, padx=10)
- sl = tk.Scale(fr1, from_=1, to=100, orient=tk.HORIZONTAL, length=250, variable=var2)
- sl.grid(row=1, column=1, padx=10, pady=10)
- label3 = tk.Label(fr1, text='是否粗体')
- label3.grid(row=2, column=0, pady=10, padx=10)
- ck = tk.Checkbutton(fr1, text='使用粗体', variable=var3)
- ck.grid(row=2, column=1, padx=10, pady=10)
-
- def a():
- aa = var.get().rstrip()
- bb = var2.get()
- cc = var3.get()
- self.fs.shange(aa, bb, "bold" if cc else "normal")
- self.font = aa
- self.size = bb
- self.bold = "bold" if cc else "normal"
- self.text.config(font=(self.font, self.size, self.bold))
- font_ = font.Font(root=self.root, font=self.text['font'])
- tab_width = font_.measure(' ' * 4)
- self.text.config(tabs=(tab_width,))
- root.destroy()
-
- btn = tk.Button(fr1, text='确认', command=a)
- btn.grid(row=3, column=0, padx=10, pady=10)
- fr2 = tk.Frame(root)
- notepad.add(fr2, text='预览')
- sb = tk.Scrollbar(fr2, orient=tk.HORIZONTAL)
- sb.pack(side=tk.BOTTOM, fill=tk.X)
- text = ts.ScrolledText(fr2, width=300, height=200, wrap='none', xscrollcommand=sb.set)
-
- def textv(*args):
- text.config(font=(var.get().rstrip(), var2.get(), "bold" if var3.get() else "normal"))
- root.geometry('%dx%d' % (600, 550))
-
- def labelv(*args):
- root.geometry('%dx%d' % (350, 220))
-
- text.bind('
' , textv) - label.bind('
' , labelv) - text.insert(tk.END, '''
- abcdefghijklmnopqrstuvwxyz
- ABCDEFGHIJKLMNOPQRSTUVWXYZ
- CASM editor is a small and lightweight editor.
- CASM editor是一个小巧轻量的编辑器。
- CASM Editor - это небольшой и легкий редактор.
- CASM editorは小型軽量のエディタです。
- CASM editor는 작고 가벼운 편집기입니다.
- CASM တည်းဖြတ်ချက်ဟာ ချိတ်ဆက်နဲ့ လျှော့လင့်တဲ့ တည်းဖြတ်ချက်ပါ။
- Casm Editor est un éditeur petit et léger.
- Editor CASM editor compact and lightweight editor est.
- El editor casm es un editor pequeño y ligero.
- CASM editor é um editor compacto e leve.
- المستخلصات المحرر هو صغير وخفيف الوزن المحرر .
- CASM सम्पादकम्य सङ्केतं चित्रकं सम्पादकम्
- ເຄື່ອງມືແກ້ໄຂCAS ເປັນຜູ້ກ່ຽວກັບຄຳແກ້ກແລະຄຳແກ້ໄຫລາຍດິນ
- ''')
- text.config(font=(var.get().rstrip(), var2.get(), "bold" if var3.get() else "normal"))
- sb.config(command=text.xview)
- text.pack()
- notepad.pack()
- root.mainloop()
-
- def elsekey(self):
- root = tk.Toplevel()
- root.title('其他')
- text = ts.ScrolledText(root)
- try:
- root.iconbitmap(r'images\lego.ico')
- except tkinter.TclError:
- pass
- text.config(font=(self.font, self.size, self.bold))
- text.insert(1.0, '\n*****************快捷键*******************\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '1. 复制 Ctrl+c\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '2. 粘贴 Ctrl+v\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '3. 剪切 Ctrl+x\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '4. 重做 Ctrl+z\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '5. 返回 Ctrl+y\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '6. 全选 Ctrl+a\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '******************作者*******************\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '1. 他叫曹高远,来自河北保定\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '\n')
- text.insert(tk.END, '\n')
- text.configure(state=tk.DISABLED)
- text.pack(side=tk.BOTTOM, fill=tk.BOTH)
- root.mainloop()
-
- def when_exit_do(self):
- global running
- if not self.running:
- if self.saved:
- self.save()
- if self.saved:
- self.root.destroy()
- self.myrun = False
- if running == 1:
- sys.exit(0)
- else:
- running -= 1
-
- else:
- a = tm.askyesnocancel('CASM文本编辑器', '你没有保存文件,是否保存后再退出?')
- if a:
- self.save()
- if self.saved:
- self.root.destroy()
- self.myrun = False
- if running == 1:
- sys.exit(0)
- else:
- running -= 1
- elif a is None:
- pass
- else:
- self.myrun = False
- self.root.destroy()
- self.myrun = False
- if running == 1:
- sys.exit(0)
- else:
- running -= 1
- else:
- tm.showerror('文本编辑器', '文件正在运行,请先关闭。')
-
- def about_file(self):
- if self.name != '':
- root = tk.Toplevel()
- root.title('关于文件')
- root.geometry('600x500')
- try:
- root.iconbitmap(r'images\lego.ico')
- except tkinter.TclError:
- pass
- label = tk.Label(root)
- string = f"""
- 文件名: {os.path.basename(self.name)}
- 文件路径: {self.name}
- 拓展名: {os.path.splitext(self.name)[-1]}
- 大小: {round(os.path.getsize(self.name) / 1024, 2)} kb ({round(os.path.getsize(self.name), 2)} b)
- """
- label.config(text=string)
- label.pack()
- root.mainloop()
-
- else:
- self.mycallsave()
-
-
- def check():
- system = os.name
- if system != 'nt':
- tm.showerror('ERROR!', '本程序只支持Microsoft Windows系统。')
- raise SystemExit('SYSTEM ERROR!')
- root = T_tk.Tk()
- root.withdraw()
- if 'casm.exe' in os.listdir(os.path.dirname(os.path.abspath(__file__))):
-
- tm.showinfo('恭喜!', '一切正常,您可以使用本编辑器!')
- else:
- tm.showerror('错误', '请确保您的电脑上已安装CASM。')
- sys.exit()
- root.destroy()
-
-
- def hello():
- root = T_tk.Tk()
- root.title('Hello-CASM editor %s' % version)
- root.resizable(False, False)
- root.attributes("-topmost", True)
- try:
- root.iconbitmap(r'images\lego.ico')
- except tkinter.TclError:
- pass
- try:
- img = tk.PhotoImage(file=r'23.4.1/images\lego.png')
- label = tk.Label(root, image=img)
- label.pack()
- except tkinter.TclError:
- pass
- label2 = tk.Label(root, text='正在加载中,请稍后……', font=('宋体', 25))
- label2.pack()
- pr = tkinter.ttk.Progressbar(root, length=700)
- pr['maximum'] = 100
- pr['value'] = 0
- pr.pack()
-
- def a():
- try:
- for i in range(100):
- pr['value'] += 1
- label2.configure(text=f'正在加载…… ( {i}% )')
- root.update()
- time.sleep(0.01)
- label2.configure(text=f'正在加载…… ( 100% ),完成!')
- root.update()
- time.sleep(0.001)
- except (tkinter.TclError, RuntimeError, Exception):
- return
- label2.configure(text=f'按窗口内任意位置以继续……')
- root.update()
-
- def aa(*args, **kwargs):
- root.destroy()
-
- root.bind('
' , aa) -
- try:
- a()
- except tkinter.TclError:
- return
- root.mainloop()
-
-
- def new():
- gui = GUI()
- gui.run()
-
-
- def main():
- try:
- new()
- T_tk.mainloop()
- except (RuntimeError, tkinter.TclError, KeyboardInterrupt):
- sys.exit()
-
-
- if __name__ == '__main__':
- main()
粘贴完直接成3万字“长文……”
下载链接:https://pan.baidu.com/s/1XNGPgbkfiu-vPXSRqzHtcw?pwd=cgy6
提取码:cgy6
