如何将代码中的pse.bind补全(文件树功能实现 -> 路径显示框,第559行),实现换行后再文件树内显示输入的路径下的文件,如果输入路径不存在就print报错?
import sys,os
import tkinter as tk
from tkinter import ttk,scrolledtext
from tkinter.messagebox import askyesnocancel as aync,showwarning as warn,showinfo as info,showerror as serr
from tkinter.filedialog import asksaveasfilename as asfn
from PIL import ImageTk,Image
from tkinter import PhotoImage
import easygui
import string
import os
import time
import ctypes
from functools import partial
import chardet
import re
import idlelib.colorizer as idc
import idlelib.percolator as idp
import subprocess
import signal
import threading
import psutil
import math
import random
from CUTool import infoTool
#获取当前文件位置
pythonRunningPath = os.getcwd()
#获取配置文件
default_cfgdic = {"tcfgTWv":1, # 自动换行
"tcfgRSv":1, # 自动保存
"lofPath":"" # 上一次打开的文件
}
if os.path.exists("./pythonRunning.ini"):
with open("./pythonRunning.ini","r",encoding = "utf-8") as f:
cfgdic = f.read().split("\n")
cfgdics = {}
for i in cfgdic:
cfgdics[i.split(":")[0]] = i.split(":")[1]
cfgdic = cfgdics
del cfgdics
else:
with open("./pythonRunning.ini","w",encoding = "utf-8") as f:
f.write(f"tcfgTWv:{default_cfgdic['tcfgTWv']}\ntcfgRSv:{default_cfgdic['tcfgRSv']}")
f.write(f"\nlofPath:{default_cfgdic['lofPath']}")
cfgdic = default_cfgdic
#带行数文本框实现
class TextLineNumbers(tk.Canvas):
def __init__(self,*args, **kwargs):
tk.Canvas.__init__(self, *args, **kwargs)
self.textwidget = None
def attach(self, text_widget):
self.textwidget = text_widget
def redraw(self, *args):
'''redraw line numbers'''
self.delete("all")
# ====================self.textwidget.index("@0,0") @0,0表示最接近左上角的行信息.
i = self.textwidget.index("@0,0") # 找到0行0列的信息. ref: 参考文档: https://tkdocs.com/shipman/text-index.html
hang, lie = i.split('.')
while True:
dline = self.textwidget.dlineinfo(i)
hang, lie = i.split('.') # 计算上面i行的信息. self.textwidget.get(i)
debug222 = self.textwidget.get(i) # 这里面显示滚动之后的左上角第一个字.#这时候我们读入的是1.4
if dline is None: break # Return tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX.
if lie == '0': # ===首列才画行号.
y = dline[1]
linenum = hang # 行信息
self.create_text(1, y, anchor="nw", text="{0:>2}".format(linenum),font = font) # 创建行号. 2是x索引.
# i = self.textwidget.index("%s+1line" % i) #然后计算下一行.
i = self.textwidget.index(str(int(hang) + 1) + '.' + '0') # 然后计算下一行.
self.config(width = 50 / 4 * len(str(hang)) + 20)
class CustomText(tk.Text):
def __init__(self,*args, **kwargs):
tk.Text.__init__(self,*args, **kwargs,font = font,autoseparators=False, undo=True,maxundo=codeMaxUndo)
self.config(wrap = tk.NONE)
'''
# create a proxy for the underlying widget
self._orig = self._w + "_orig"
self.tk.call("rename", self._w, self._orig)
self.tk.createcommand(self._w, self._proxy)'''
self.bind('<Key>',self.callback)
#绑定撤回/取消撤回事件
self.bind("<Control-KeyPress-Z>",self.undo)
self.bind("<Control-KeyPress-Y>",self.redo)
def undo(self,event = None):
self.edit_undo()
def redo(self,event = None):
self.edit_redo()
def callback(self,event = None):
self.edit_separator()
def copy(self,event = None):
self.event_generate("<<Copy>>")
def paste(self,event = None):
self.event_generate("<<Paste>>")
def cut(self,event = None):
self.event_generate("<<Cut>>")
def _proxy(self, *args): #发送自定义信号change
# let the actual widget perform the requested action
result=1
try:
cmd = (self._orig,) + args
result = self.tk.call(cmd)
# generate an event if something was added or deleted,
# or the cursor position changed
if (args[0] in ("insert", "replace", "delete") or
args[0:3] == ("mark", "set", "insert") or
args[0:2] == ("xview", "moveto") or
args[0:2] == ("xview", "scroll") or
args[0:2] == ("yview", "moveto") or
args[0:2] == ("yview", "scroll")
):
self.event_generate("<<Change>>", when="tail")#触发change信号.
except:
pass
# return what the actual widget returned
return result
class Example(tk.Frame):
def __init__(self,*args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.text = CustomText(self)
self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)#竖直方向的滑动杆.
self.xsb = tk.Scrollbar(self,orient = tk.HORIZONTAL,command = self.text.xview)
self.text.configure(xscrollcommand = self.xsb.set,yscrollcommand=self.vsb.set)
self.linenumbers = TextLineNumbers(self, width=30)#创建行号工具
self.linenumbers.attach(self.text) # 绑定行号工具到text空间.
self.vsb.pack(side="right", fill="y")
self.xsb.pack(side = tk.BOTTOM,fill = tk.X)
self.linenumbers.pack(side="left", fill="y")
self.text.pack(side="right", fill="both", expand=True)
self.text.bind("<<Change>>", self._on_change)#绑定修改到重新绘制linenumber
self.text.bind("<Configure>", self._on_change)
def _on_change(self, event):
self.linenumbers.redraw()
def xview(self,*args):
CustomText.xview(*args)
#输出文本框实现
class OutputTextLineNumbers(tk.Canvas):
def __init__(self,*args, **kwargs):
tk.Canvas.__init__(self, *args, **kwargs)
self.textwidget = None
def attach(self, text_widget):
self.textwidget = text_widget
def redraw(self, *args):
'''redraw line numbers'''
self.delete("all")
# ====================self.textwidget.index("@0,0") @0,0表示最接近左上角的行信息.
i = self.textwidget.index("@0,0") # 找到0行0列的信息. ref: 参考文档: https://tkdocs.com/shipman/text-index.html
hang, lie = i.split('.')
while True:
dline = self.textwidget.dlineinfo(i)
hang, lie = i.split('.') # 计算上面i行的信息. self.textwidget.get(i)
debug222 = self.textwidget.get(i) # 这里面显示滚动之后的左上角第一个字.#这时候我们读入的是1.4
if dline is None: break # Return tuple (x,y,width,height,baseline) giving the bounding box and baseline position of the visible part of the line containing the character at INDEX.
if lie == '0': # ===首列才画行号.
y = dline[1]
linenum = infoTool.infoget("",prints = False) # 行信息
self.create_text(1, y, anchor="nw", text="{0:>2}".format(linenum),font = font) # 创建行号. 2是x索引.
# i = self.textwidget.index("%s+1line" % i) #然后计算下一行.
i = self.textwidget.index(str(int(hang) + 1) + '.' + '0') # 然后计算下一行.
self.config(width = 50 / 4 * len(str(hang)) + 20)
class OutputText(tk.Frame):
def __init__(self,*args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
self.text = CustomText(self)
self.vsb = tk.Scrollbar(self, orient="vertical", command=self.text.yview)#竖直方向的滑动杆.
self.xsb = tk.Scrollbar(self,orient = tk.HORIZONTAL,command = self.text.xview)
self.text.configure(xscrollcommand = self.xsb.set,yscrollcommand=self.vsb.set)
self.linenumbers = OutputTextLineNumbers(self, width=50)#创建行号工具
self.linenumbers.attach(self.text) # 绑定行号工具到text空间.
self.vsb.pack(side="right", fill="y")
self.xsb.pack(side = tk.BOTTOM,fill = tk.X)
self.linenumbers.pack(side="left", fill="y")
self.text.pack(side="right", fill="both", expand=True)
self.text.bind("<<Change>>", self._on_change)#绑定修改到重新绘制linenumber
self.text.bind("<Configure>", self._on_change)
def _on_change(self, event):
self.linenumbers.redraw()
def xview(self,*args):
CustomText.xview(*args)
#硬盘获取
def hetDiskList():
l = []
for c in string.ascii_uppercase:
disk = c + ':\\'
if os.path.isdir(disk):
l.append(disk)
#drive_node = tree_view.insert(pc_node, 'end', text=disk, image=drive_image)
return l
#获取选中的节点路径中的文件与文件夹
def node_path(node):
path = ''
parent = node
while parent:
node_text = tree_view.item(parent, 'text')
if len(path) > 0:
path = os.path.join(node_text, path)
else:
path = node_text
parent = tree_view.parent(parent)
return path
#在文件夹中添加节点
def insert_child_items(parent_node):
path = node_path(parent_node)
dirlist = []
filelist = []
if os.path.isdir(path):
try:
dir_items = os.scandir(path)
for item in dir_items:
if item.name == "$RECYCLE.BIN" or item.name == "$Recycle.Bin":
tree_view.insert(parent_node, 'end', text=item.name, image=recycle_image)
else:
if item.is_dir() and ('.$'.find(item.name[0])<0):
dirlist.append(item.name)
else:
if not "$" in item.name:
filelist.append(item.name)
else:
dirlist.append(item.name)
#添加节点
dirlist.sort()
filelist.sort()
for item in dirlist:
tree_view.insert(parent_node, 'end', text=item, image=folder_image)
for item in filelist:
tree_view.insert(parent_node, 'end', text=item, image=file_image)
except Exception as e:
print(e)
#展开节点事件
def open_node(event):
focus = tree_view.focus()
for node in tree_view.get_children(focus):
insert_child_items(node)
#关闭节点事件
def close_node(event):
focus = tree_view.focus()
for node in tree_view.get_children(focus):
children = tree_view.get_children(node)
for c in children:
tree_view.delete(c)
#选择节点事件
def select_node(event):
if tree_view.focus() == "I001":
print("=I001",node_path(tree_view.focus()),tree_view.focus())
return
path = node_path(tree_view.focus())
pse.delete(0,tk.END)
pse.insert(0,path)
print(path)
#窗口关闭事件
def closewin():
if saveFile():
win.destroy()
try:
for child in find_child_processes(pypro.pid):
child.terminate()
pypro.kill()
except:pass
print("\n---退出程序---")
os._exit(0)
#运行py程序函数
def find_child_processes(pid):
for process in psutil.process_iter():
if process.ppid() == pid:
yield process
def whileCheck():
while True:
if pypro.poll() != None:
sb.config(state = tk.DISABLED)
rb.config(state = tk.NORMAL)
runfm.delete(0,1)
runfm.add_command(label = "运行",command = partial(runPythonFile,"run"))
runfm.add_command(label = "终止",command = partial(runPythonFile,"stop"),state = tk.DISABLED)
print("---程序运行子进程结束---")
lineNum = 0
return
def runPythonFile(mod = "run"):
global pypro,openFileDir,lineNum
lineNum = 0
def read_output(pipe,mod):
global lineNum
print(f"StartReadOutput:mod={mod}")
if mod == "err":
cst = cset
else:
cst = csot
cst.tag_configure("gray", foreground="lightgray")
cst.tag_configure("blue", foreground="blue")
for i in iter(pipe.readline,b''):
line = i.strip().decode("utf-8") + "\n"
print(f"std{mod} >> {line}",end = "")
cst.config(state = tk.NORMAL)
cst.insert(tk.END,"[%05d]" % lineNum,"gray")
cst.insert(tk.END,line,mod)
cst.config(state = tk.DISABLED)
cst.see(tk.END)
win.update()
lineNum += 1
if lineNum >= 99999:
lineNum = 0
#time.sleep(0.05)
#pypro.stdout.close()
cst.config(state = tk.NORMAL)
cst.insert(tk.END,"----------Shell----------","blue")
cst.config(state = tk.DISABLED)
cst.see(tk.END)
print(f"\n---{mod}输出流结束---\n")
if mod == "stop":
for i in find_child_processes(pypro.pid):
i.terminate()
pypro.kill()
elif mod == "run":
saveFile()
rb.config(state = tk.DISABLED)
sb.config(state = tk.NORMAL)
runfm.delete(0,1)
runfm.add_command(label = "运行",command = partial(runPythonFile,"run"),state = tk.DISABLED)
runfm.add_command(label = "终止",command = partial(runPythonFile,"stop"))
#清空文本框
csot.config(state = tk.NORMAL)
csot.delete("1.0",tk.END)
csot.config(state = tk.DISABLED)
cset.config(state = tk.NORMAL)
cset.delete("1.0",tk.END)
cset.config(state = tk.DISABLED)
if openFileDir["path"] and os.path.splitext(os.path.basename(openFileDir["path"]))[1] == ".py":
if not os.path.exists(openFileDir["path"]):
serr(title = "错误",message = f"错误:\n{openFileDir['path']}\n文件不存在!")
return
try:
pypro = subprocess.Popen([f"{pythonRunningPath}\\python37\\python.exe",openFileDir["path"]],
stdout = subprocess.PIPE,
stderr = subprocess.PIPE,
shell = False,
cwd = os.path.dirname(openFileDir["path"]),
bufsize = 0)
t1 = threading.Thread(target=read_output, args=(pypro.stdout,"out"))
t2 = threading.Thread(target=read_output, args=(pypro.stderr,"err"))
threading.Thread(target = whileCheck).start()
t1.start()
t2.start()
except Exception as e:
print(e)
serr(title = "错误",message = f"运行出错!\n{e}")
return
#保存文件函数
def saveFile():
if not isAutoSave:
a = aync(title = "警告",message = "是否保存?")
else:
a = True
if a:
try:os.makedirs(openFileDir["path"])
except:pass
savepath = openFileDir["path"]
saveencoding = openFileDir["encoding"]
# 如果目录不存在或者不是打开的文件询问保存位置和编码
if (not openFileDir["path"]) or (not os.path.exists(openFileDir["path"])):
if code.text.get("1.0",tk.END) == "\n":return True
savepath = asfn(title = "请选择保存路径")
print(savepath)
if not savepath:return True
#询问编码
if not saveencoding:
saveencoding = easygui.buttonbox("请选择编码","请选择编码",("GBK","GB2312","utf-8","ascii","[bit]"))
print("保存文件-选择完毕")
if not (savepath and saveencoding):
print(f"未选择保存路径或编码,退出函数(savepath:'{savepath}',saveencoding:'{saveencoding}')")
return None
if saveencoding == "[bit]":
with open(savepath,"wb") as f:
f.write(code.text.get("1.0",tk.END))
else:
with open(savepath,"w",encoding = saveencoding) as f:
f.write(code.text.get("1.0",tk.END))
elif a == None:
return None
return True
#--------------------创建窗口--------------------#
win = tk.Tk()
win.title("pythonRunning")
winsize = (1200,700)
scrsize = (win.winfo_screenwidth(),win.winfo_screenheight())
win.geometry("{}x{}+{}+{}".format(*winsize,(scrsize[0] - winsize[0]) // 2,(scrsize[1] - winsize[1]) // 2))
#win.resizable(0,0)
#win.maxsize(width=scrsize[0], height=scrsize[1])
win.protocol('WM_DELETE_WINDOW',closewin)
win.grid_rowconfigure(0, weight=1)
win.grid_columnconfigure(0, weight=1)
#告诉操作系统使用程序自身的dpi适配
ctypes.windll.shcore.SetProcessDpiAwareness(1)
#获取屏幕的缩放因子
ScaleFactor=ctypes.windll.shcore.GetScaleFactorForDevice(0)
#设置程序缩放
win.tk.call('tk', 'scaling', ScaleFactor/75)
#-------------------窗口组件绘制------------------#
pwin = tk.PanedWindow(win, orient=tk.HORIZONTAL,sashrelief = "raised",sashwidth = 5,relief = "sunken")
pwinr = tk.PanedWindow(pwin,orient = tk.VERTICAL,sashrelief = "raised",sashwidth = 5,relief = "sunken")
pwin.grid(row=0, column=0, sticky='wnse')
#文件树
tree_area = tk.Frame(pwin)
tree_area.grid_rowconfigure(1, weight=1)
tree_area.grid_columnconfigure(0, weight=1)
#代码框
font = ("Consolas",14)
codeMaxUndo = 2200000000
print(f"codeMaxUndo:{codeMaxUndo}, font:{font}")
cf = ttk.Labelframe(pwinr,text = "代码")
cf.pack(padx = 10,pady = 10)
code = Example(cf)
#code.text.bind("<Key>",highLightCode)
idc.color_config(code.text)
code.text.focus_set()
code.text.config(bg='white',fg='black')
p = idp.Percolator(code.text)
d = idc.ColorDelegator()
p.insertfilter(d)
#code.config(yscrollcommand = cscr.set)
#line.config(yscrollcommand = cscr.set)
code.pack(fill = tk.BOTH)
pwinr.add(cf,minsize = 20,height = 450,padx = 5,pady = 5)
#运行框
rf = ttk.Labelframe(pwinr,text = "运行(某些程序可能无法显示输出,输出流可能会卡顿)")
rbf = tk.Frame(rf)
rb = ttk.Button(rbf,text = "运行",command = partial(runPythonFile,"run"),state = tk.DISABLED)
sb = ttk.Button(rbf,text = "终止",command = partial(runPythonFile,"stop"),state = tk.DISABLED)
cstpw = tk.PanedWindow(rf,orient=tk.HORIZONTAL,sashrelief = "raised",sashwidth = 5,relief = "sunken")
csof = tk.Frame(cstpw)
csol = tk.Label(csof,text = "stdout:",anchor = tk.W)
csot = tk.Text(csof,state = tk.DISABLED,font = font,wrap = tk.NONE,fg = "black")
cxso = tk.Scrollbar(csof, orient=tk.HORIZONTAL, command=csot.xview)
cyso = tk.Scrollbar(csof,orient = tk.VERTICAL,command = csot.yview)
csot.configure(xscrollcommand = cxso.set,yscrollcommand=cyso.set)
csef = tk.Frame(cstpw)
csel = tk.Label(csef,text = "stderr:",anchor = tk.W)
cset = tk.Text(csef,state = tk.DISABLED,font = font,wrap = tk.NONE,fg = "red")
cxse = tk.Scrollbar(csef, orient=tk.HORIZONTAL, command=cset.xview)
cyse = tk.Scrollbar(csef,orient = tk.VERTICAL,command = cset.yview)
cset.configure(xscrollcommand = cxse.set,yscrollcommand=cyse.set)
cstpw.add(csof,width = 430,minsize = 20)
cstpw.add(csef,minsize = 20)
rbf.pack(side = tk.TOP,fill = tk.X)
rb.pack(side = tk.LEFT)
sb.pack(side = tk.LEFT)
cstpw.pack(fill = tk.BOTH)
csol.pack(fill = tk.X)
cxso.pack(side = tk.BOTTOM,fill = tk.X)
cyso.pack(side="right", fill="y")
csot.pack(fill = tk.BOTH)
csel.pack(fill = tk.X)
cxse.pack(side = tk.BOTTOM,fill = tk.X)
cyse.pack(side="right", fill="y")
cset.pack(fill = tk.BOTH)
pwinr.add(rf,minsize = 20,padx = 5,pady = 5)
#将组件添加到pwin里
pwin.add(tree_area,minsize = 100,width = 300)
pwin.add(pwinr,minsize = 100)
#--------------------窗口menu--------------------#
menu = tk.Menu(win)
win.config(menu = menu)
filem = tk.Menu(menu, tearoff=False)
menu.add_cascade(label='File', menu=filem)
filem.add_command(label="Open", command = partial(print,"Open"))
filem.add_command(label="Save", command = saveFile)
filem.add_separator()
filem.add_command(label="Delete", command = partial(print,"Delete"))
filem.add_command(label="Create", command = partial(print,"Create"))
filem.add_command(label="Exit", command=win.quit)
editm = tk.Menu(menu,tearoff = False)
menu.add_cascade(label='Edit', menu=editm)
editm.add_command(label = "Undo",command = code.text.undo)
editm.add_command(label = "Redo",command = code.text.redo)
editm.add_command(label = "Copy",command = code.text.copy)
editm.add_command(label = "Paste",command = code.text.paste)
editm.add_command(label = "Cut",command = code.text.cut)
editm.add_separator()
tcfgm = tk.Menu(menu,tearoff = False)
menu.add_cascade(label='Config', menu=tcfgm)
def textWrap():
global tcfgTWv
print(tcfgTWv.get())
if tcfgTWv.get() == 1:
#tcfgTWv.set(1)
code.text.config(wrap = tk.WORD)
else:
#tcfgTWv.set(0)
code.text.config(wrap = tk.NONE)
win.update()
isAutoSave = False
def reIsSave():
global isAutoSave
if tcfgRSv.get():
isAutoSave = True
else:
isAutoSave = False
tcfgTWv = tk.IntVar()
tcfgRSv = tk.IntVar()
tcfgTWv.set(int(cfgdic["tcfgTWv"]))
tcfgRSv.set(int(cfgdic["tcfgRSv"]))
if int(cfgdic["tcfgTWv"]):textWrap()
if int(cfgdic["tcfgRSv"]):reIsSave()
tcfgm.add_checkbutton(label = "自动换行",command = textWrap,variable = tcfgTWv)
tcfgm.add_checkbutton(label = "自动保存",command = reIsSave,variable = tcfgRSv)
runfm = tk.Menu(menu,tearoff = False)
menu.add_cascade(label='Run', menu=runfm)
runfm.add_command(label = "运行",command = partial(runPythonFile,"run"),state = tk.DISABLED)
runfm.add_command(label = "终止",command = partial(runPythonFile,"stop"),state = tk.DISABLED)
#------------------文件树功能实现------------------#
#加载图像
cur_path = os.path.abspath(os.path.dirname(__file__))
pc_image = PhotoImage(file=cur_path + '\\images\\pc.png')
drive_image = PhotoImage(file=cur_path + '\\images\\drive.png')
folder_image = PhotoImage(file=cur_path + '\\images\\folder.png')
file_image = PhotoImage(file=cur_path + '\\images\\file.png')
recycle_image = PhotoImage(file = cur_path + "\\images\\recycle.png")
#路径显示框
psf = tk.Frame(tree_area)
psl = ttk.Label(psf,text = "路径")
pse = ttk.Entry(psf)
pse.bind("<Enter>",)
psf.grid(row=0, column=0, sticky = "ew")
psl.grid(row = 0,column = 0)
pse.grid(row = 0,column = 1,sticky = "ew")
psf.grid(row = 0,column = 0,sticky = "ew",columnspan = 2)
psf.grid_columnconfigure(1,weight = 1)
#文件树组件
tree_view = ttk.Treeview(tree_area, show='tree', selectmode='browse')
tree_view.grid(row=1, column=0, sticky='nsew')
#滚动条
scroll_ty = tk.Scrollbar(tree_area, orient=tk.VERTICAL, command=tree_view.yview)
scroll_ty.grid(row=1, column=1, sticky="ns")
tree_view['yscrollcommand']=scroll_ty.set
#pc图标(初始内容)
pc_node= tree_view.insert('', 'end',
text=os.environ.get('COMPUTERNAME'),
image=pc_image,
open = False)
#添加硬盘节点(pc节点内)
for i in hetDiskList():
drive_node = tree_view.insert(pc_node, 'end', text=i, image=drive_image)
#-------------------获取传入参数-------------------#
def getArgv():
try:
print("传入的内容:",sys.argv)
if len(sys.argv) > 2:
print(f"传入了 {len(sys.argv) - 1} 个文件,当前打开 {sys.argv[1]} 文件")
openfilepath = sys.argv[1]
print("传入的文件:",openfilepath)
if not os.path.exists(openfilepath):
print("该文件不存在!")
serr("pythonRunning-Error",f"传入的文件{openfilepath}不存在!")
try:win.destroy()
except:pass
os._exit(0)
return openfilepath
except:
print("没有传参")
return None
#选择文件函数(配合打开文件函数openFile使用)
def chooseFile(event):
focus = tree_view.focus()
path = node_path(focus)
if os.path.isfile(path):
openFile(path)
#打开文件函数
openFileDir = {"path":None,"encoding":None,"file":None}
def get_encoding(file):# 获取文件编码类型
# 二进制方式读取,获取字节数据,检测类型
try:
with open(file, 'rb') as f:
data = f.read()
return chardet.detect(data)['encoding']
except Exception as e:
print(f"Err:{e}")
def openFile(path):
global fileEncoding,openFileDir
print("要打开的文件:",path)
if not os.path.isfile(path):
print("不是一个有效的文件!")
serr(title = "错误",message = f"{path}\n不是一个有效的文件!")
return
if not os.path.exists(path):
print("文件不存在!")
serr(title = "错误",message = f"{path}\n文件不存在!")
return
fileEncoding = get_encoding(path)
print("文件编码:",fileEncoding)
print(fileEncoding)
if not fileEncoding:
fileEncoding = easygui.buttonbox("请选择编码","请选择编码",("GBK","GB2312","utf-8","ascii","[bit]"))
if not fileEncoding:
print(f"未选择编码,退出函数(fileEncoding:{fileEncoding})")
return
print(fr"'{code.text.get('1.0',tk.END)}'")
ttt = """'
'""".replace("'","")
if code.text.get("1.0",tk.END) != "\n" or code.text.get("1.0",tk.END) != ttt:
saveFile()
print("基本检查完毕,可以打开文件")
try:
if fileEncoding == "[bit]":
file = open(path,"rb")
else:
file = open(path,"r",encoding = fileEncoding)
code.text.delete("1.0",tk.END)
code.text.insert(tk.END,str(file.read()))
code.linenumbers.redraw()
openFileDir = {"path":path,"encoding":fileEncoding,"file":file}
win.title(f"pythonRunning - {path}")
cf.config(text = f"代码 - {path}")
except Exception as e:
print(f"打开文件失败!Err:{e}")
serr(title = "错误",message = f"打开文件失败!\nErr:{e}")
print("文件已打开!")
rb.config(state = tk.NORMAL)
runfm.delete(0)
runfm.add_command(label = "运行",command = partial(runPythonFile,"run"))
#如有传参打开文件
openfilepath = getArgv()
if openfilepath:
openFile(openfilepath)
#绑定事件
tree_view.bind('<<TreeviewSelect>>', select_node)
tree_view.bind('<<TreeviewOpen>>', open_node)
tree_view.bind('<<TreeviewClose>>', close_node)
tree_view.bind("<Double-Button-1>",chooseFile)
#窗口内快捷键
def WINrunPythonFile(event = None):
if str(rb.cget("state")) == "normal":runPythonFile("run")
def WINstopPythonFile(event = None):
print(sb.cget("state"))
if str(sb.cget("state")) == tk.NORMAL:runPythonFile("stop")
win.bind("<F9>",WINrunPythonFile)
win.bind("<Control-Alt-F9>",WINstopPythonFile)
def WINsaveFile(event = None):saveFile()
win.bind("<Control-S>",WINsaveFile)
#打开上一次的文件
if cfgdic["lofPath"]:
openFile(cfgdic["lofPath"])
win.mainloop()