import ttkbootstrap as ttk
import tkinter as tk
from tkinter import messagebox, filedialog, PhotoImage
import os
from collections import defaultdict
class pyAether(object):
def __init__(self, window):
self.window = window
self.dic = defaultdict(list)
if os.path.exists('pyAether.cfg'):
with open('pyAether.cfg', 'r', encoding='utf-8') as f:
for line in f:
if len(line.split(' ')) > 1:
self.dic[str(line.split(',')[0].strip())] = line.split(',')[-1].strip()
self.change = self.redo = self.text = self.file = False
self.windowMenu(window)
self.oneFrame(window)
self.pv_config()
def tureClose(self):
if self.change:
if messagebox.askokcancel(title="退出", message="文件未保存,是否确认退出?"):
self.window.destroy()
else:
if messagebox.askokcancel(title="退出", message="确认退出?"):
self.window.destroy()
def openMeunFile(self):
file = filedialog.askopenfilename(title='选择文件', filetypes=[('py', '__init__.py'), ('all', '.*')], defaultextension='.py')
if file:
self.textEdit(file)
self.entry2.delete(0, "end")
self.entry2.insert(0, os.path.dirname(file))
self.file = file
def textEdit(self, file):
text = tk.Text(self.frame, font=('KaiTi', 10), wrap='none', height=1, undo=True, autoseparators=False, maxundo=-1)
text.grid(row=1, column=0, columnspan=4, padx=15, pady=10, sticky='nsew')
with open(file, 'r', encoding='utf-8') as f:
for num, line in enumerate(f):
text.insert(float(num + 1), line)
text.configure(state='normal')
self.text = text
self.redo = 0
text.bind("<Key>", self.callback)
def callback(self, event):
if self.text:
self.text.edit_separator()
self.change = True
def saveFile(self):
if self.file:
f = open(self.file, 'w+', encoding='utf-8')
f.write(str(self.text.get(1.0, 'end')))
f.close()
self.change = False
def saveAsFile(self):
if self.text:
self.file = filedialog.asksaveasfilename()
if self.file:
self.saveFile()
else:
messagebox.showwarning("警告", "您未打开文件!")
def undoFile(self):
if self.text and len(self.text.get('1.0', 'end')) > 1:
self.text.edit_undo()
self.redo += 1
def reundioFile(self):
if self.text and self.redo > 0:
self.text.edit_redo()
self.redo -= 1
def windowMenu(self, window):
window.title("pyAether Pcell")
winSize = (window.winfo_screenwidth() // 3, window.winfo_screenheight() // 2)
xCoord = int((window.winfo_screenwidth() / 2) - (winSize[0] / 2))
yCoord = int((window.winfo_screenheight() / 2) - (winSize[1] / 2))
window.geometry("%dx%d+%d+%d" % (winSize[0], winSize[1], xCoord, yCoord))
window.protocol("WM_DELETE_WINDOW", self.tureClose)
window.bind("<Escape>", lambda event: window.destroy())
Menu = ttk.Menu(self.window, tearoff=False)
oneMenu = ttk.Menu(Menu, tearoff=False)
oneMenu.add_command(label="打开", accelerator="Ctrl+O", command=self.openMeunFile)
window.bind('<Control-o>', lambda event: self.openMeunFile())
oneMenu.add_separator()
oneMenu.add_command(label="保存", accelerator="Ctrl+S", command=self.saveFile())
window.bind('<Control-s>', lambda event: self.saveFile())
oneMenu.add_separator()
oneMenu.add_command(label="另存为", accelerator="", command=self.saveAsFile)
Menu.add_cascade(label='文件', menu=oneMenu)
twoMenu = ttk.Menu(Menu, tearoff=False)
twoMenu.add_command(label="撤销", accelerator="Ctrl+Z", command=self.undoFile)
window.bind('<Control-z>', lambda event: self.undoFile())
twoMenu.add_separator()
twoMenu.add_command(label="反撤销", accelerator="Alt+Z", command=self.reundioFile)
window.bind('<Alt-z>', lambda event: self.reundioFile())
Menu.add_cascade(label='编辑', menu=twoMenu)
threeMenu = ttk.Menu(Menu, tearoff=False)
threeMenu.add_command(label="载入", accelerator="Ctrl+P", command=self.undoFile)
window.bind('<Control-p>', lambda event: self.undoFile())
threeMenu.add_separator()
threeMenu.add_command(label="保存", accelerator="Ctrl+P", command=self.undoFile)
window.bind('<Alt-p>', lambda event: self.undoFile())
Menu.add_cascade(label='配置', menu=threeMenu)
window.config(menu=Menu)
def oneFrame(self, window: tk.Tk):
frame = ttk.Frame(self.window, relief='ridge', borderwidth=0)
frame.rowconfigure(1, weight=1)
frame.columnconfigure(1, weight=1)
frame.pack(expand=True, fill='both')
self.frame = frame
ttk.Label(frame).grid(row=0, column=0, padx=15, pady=0, sticky="nsew")
ttk.Labelframe(frame, text='__init__.py设置', bootstyle='info').grid(row=0, rowspan=2, column=0, columnspan=4, padx=5, pady=0, sticky='nsew')
ttk.Label(frame).grid(row=3, column=0, padx=15, pady=0, sticky="nsew")
ttk.Labelframe(frame, text='pyAether设置', bootstyle='success').grid(row=2, rowspan=4, column=0, columnspan=4, padx=5, pady=0, sticky='nsew')
ttk.Label(frame, text="PCell路径:", bootstyle='DANGER').grid(row=4, column=0, padx=15, pady=5, sticky="nsew")
self.entry1 = tk.Entry(frame, validate="key", show="", font=("KaiTi", 15))
self.entry1.grid(row=4, column=1, padx=0, pady=5, sticky="nsew")
ttk.Label(frame, text="脚本路径:", bootstyle='DANGER').grid(row=5, column=0, padx=15, pady=5, sticky="nsew")
self.editvar = tk.StringVar(value="")
self.entry2 = tk.Entry(frame, validate="key", show="", font=("KaiTi", 15), textvariable=self.editvar)
self.entry2.grid(row=5, column=1, padx=0, pady=10, sticky="nsew")
ttk.Label(frame).grid(row=6, column=0, padx=15, pady=0, sticky="nsew")
ttk.Button(frame, text="运行", bootstyle='success-outline').grid(row=4, rowspan=2, column=3, padx=15, pady=10, sticky='nsew')
def pv_config(self):
if self.dic["__init__.py路径"]:
if self.text:
self.text.delete(1.0, "end")
self.textEdit(self.dic["__init__.py路径"])
if self.dic["PCell路径"]:
self.entry1.delete(0, "end")
self.entry1.insert(0, self.dic["PCell路径"])
if self.dic["脚本路径"]:
self.entry2.delete(0, "end")
self.entry2.insert(0, self.dic["脚本路径"])
if __name__ == '__main__':
tkWindow = tk.Tk()
app = pyAether(window=tkWindow)
tkWindow.mainloop()