问题:自己写的一个类记事本程序,存在中文输入法输入“p”后会自动重置控件内容但可正常保存的bug和中文输入法输入“q”后会自动弹出另存为窗口且后续进行更改无法正常保存的bug,且找不到出错的代码
操作环境:python idle,导入了tkinter库和ctypes库(bug在导入此库前就已存在)
部分
```源码:
from tkinter import *
from tkinter.ttk import *
from tkinter import messagebox
from tkinter.filedialog import asksaveasfilename
from tkinter.filedialog import askopenfilename
from tkinter.scrolledtext import ScrolledText
from tkinter.font import Font
from ctypes import *
# 基础功能部分:
def newFile(event = None): # 新建文档
text.delete("1.0", END)
root.title("Untitled") # 标题改为Untitled
def saveAsFile(event = None): # 另存文档
global filename
textContent = text.get("1.0", END)
filename = asksaveasfilename(defaultextension = ".txt") # 打开另存为的对话框
if filename == "":
return # 若未输入文件名则不继续执行
with open(filename, "w") as output:
output.write(textContent)
root.title(filename) # 更改root窗口标题
def saveFile(event = None): # 保存文档
global filename
if filename != "Untitled":
textContent = text.get("1.0", END)
with open(filename, "w") as output:
output.write(textContent)
root.title(filename)
messagebox.showinfo("Tips", "保存成功,下次也要记得随手保存呀")
else:
saveAsFile()
def openFile(event = None): # 打开文档
global filename
filename = askopenfilename()
codeNumber = 0 # 选择列表中的第一个元素
if filename == "":
return # 若未选择文档则不继续执行
else:
codeList = ["UTF-8", "GBK", "ANSI"]
code = codeList[codeNumber]
try:
with open(filename, "r", encoding = code) as fileObj:# 尝试第一种编码格式
content = fileObj.read()
text.delete("1.0", END)
text.insert(END, content) # 插入读取的文档
root.title(filename)
except(UnicodeDecodeError):
codeNumber = codeNumber + 1
code = codeList[codeNumber] # 切换为下一种编码格式
try:
with open(filename, "r", encoding = code) as fileObj:
content = fileObj.read()
text.delete("1.0", END)
text.insert(END, content)
root.title(filename)
except(UnicodeDecodeError):
codeNumber = codeNumber + 1
code = codeList[codeNumber] # 切换为下一种编码格式
try:
with open(filename, "r", encoding = code) as fileObj:
content = fileObj.read()
text.delete("1.0", END)
text.insert(END, content)
root.title(filename)
except(UnicodeDecodeError):
messagebox.showinfo("Error", "该文档编码格式暂不能被本软件识别")
def search(): #查找
searchToplevel = Toplevel(root)
searchToplevel.title("Search")
searchToplevel.transient(root)
searchToplevel.resizable(False, False)
Label(searchToplevel, text = "Find All:").grid(row = 0, column = 0, sticky = "e")
searchEntryWidget = Entry(searchToplevel, width = 25)
searchEntryWidget.grid(row = 0, column = 1, padx = 2, pady = 2, sticky = "we")
searchEntryWidget.focus_set()
ignoreCaseValue = IntVar()
Checkbutton(searchToplevel, text = "Ignore Case 忽略大小写", variable = ignoreCaseValue).grid(
row = 1, column = 1, sticky = "e", padx = 2, pady = 2)
Button(searchToplevel, text = "Find All 全部查找", underline = 0,
command = lambda: searchOutput(searchEntryWidget.get(),
ignoreCaseValue.get(),
text,
searchToplevel,
searchEntryWidget)).grid(row = 0, column = 2, sticky = "e" + "w", padx = 2, pady = 2)
def closeSearchWindow():
text.tag_remove("match", "1.0", END)
searchToplevel.destroy()
searchToplevel.protocol("WM_DELETE_WINDOW", closeSearchWindow)
return "break"
def searchOutput(needle, ifIgnoreCase, contentText, searchToplevel, searchBox): #查找
contentText.tag_remove("match", "1.0", END)
matchesFound = 0
if needle:
startPos = "1.0"
while True:
startPos = contentText.search(needle, startPos, nocase=ifIgnoreCase, stopindex=END)
if not startPos:
break
endPos = "{}+{}c".format(startPos, len(needle))
contentText.tag_add("match", startPos, endPos)
matchesFound += 1
startPos = endPos
contentText.tag_config("match", foreground = "red", background = "yellow")
searchBox.focus_set()
searchToplevel.title("{} matches found". format(matchesFound))
def selectAll(event = None): # 全选
text.tag_add("sel", "1.0", "end")
return "break"
def copy(event = None): # 复制
text.event_generate("<<Copy>>")
return "break"
def paste(event = None): # 粘贴
text.event_generate("<<Paste>>")
return "break"
def cut(event = None): # 剪切
text.event_generate("<<Cut>>")
return "break"
def minimize(): # 最小化
root.iconify()
def undo(): # 撤销
try:
text.edit_undo()
except:
pass
def redo(): # 复原
try:
text.edit_redo()
except:
pass
# 日间/夜间模式部分:
def nightMode(): # 夜间模式
text.config(fg="white", bg="black", insertbackground="white", selectforeground="black",
selectbackground="white")
def dayMode(): # 日间模式
text.config(bg="white", fg="black", insertbackground="black", selectbackground="black",
selectforeground="white")
# 字体部分:
def Arial():
text.config(font=("Arial"))
def MicrosoftYaHei():
text.config(font=("微软雅黑"))
def CalistoMT():
text.config(font=("Calisto_MT"))
# 弹出式菜单(小窗口)部分:
def showPopupMenu(event): # 展示弹出式菜单
popupmenu.post(event.x_root, event.y_root)
# 关于部分:
# 初始配置
filename = "Untitled"
root = Tk()
root.title(filename)
root.geometry("800x600")
text = Text(root, height = 800, width = 600, wrap = "none", undo = True)
text.config(font=("微软雅黑"))
#适配高DPI:
windll.shcore.SetProcessDpiAwareness(1) # 使用程序自身dpi适配
ScaleFactor = windll.shcore.GetScaleFactorForDevice(0) # 获取屏幕缩放因子
root.tk.call("tk", "scaling", ScaleFactor/75) # 设置程序缩放
# 滚动条
xScrollBar = Scrollbar(root, orient = HORIZONTAL)
yScrollBar = Scrollbar(root)
xScrollBar.pack(side = BOTTOM, fill = X)
yScrollBar.pack(side = RIGHT,fill = Y)
xScrollBar.config(command = text.xview)
yScrollBar.config(command = text.yview)
text.config(xscrollcommand = xScrollBar.set)
text.config(yscrollcommand = yScrollBar.set)
text.pack(fill = BOTH, expand = True)
text.focus_set()
# 创建最上层菜单
menubar = Menu(root)
filemenuFile = Menu(menubar, tearoff = False)
filemenuAbout = Menu(menubar, tearoff = False)
filemenuFamily = Menu(menubar, tearoff = False)
filemenuTimeMode = Menu(menubar, tearoff = False)
# 创建弹出式菜单
popupmenu = Menu(root, tearoff = False)
# 在File菜单内建立菜单列表,便于对文档进行操作
menubar.add_cascade(label = "File", menu = filemenuFile)
filemenuFile.add_command(label = "New File 新建", command = newFile, accelerator = "F1")
root.bind("<F1>", newFile)
filemenuFile.add_command(label = "Save As File 另存为", command = saveAsFile, accelerator = "F2")
root.bind("<F2>", saveAsFile)
filemenuFile.add_command(label = "Save File 保存", command = saveFile, accelerator = "F3")
root.bind("<F3>", saveFile)
filemenuFile.add_command(label = "Open File 打开", command = openFile, accelerator = "F5")
root.bind("<F5>", openFile)
filemenuFile.add_separator()
filemenuFile.add_command(label = "Exit 退出", command = root.destroy, accelerator = "Alt + F4")
# 一些菜单工具
menubar.add_command(label = "Find", command = search)
# 在Family菜单内建立菜单列表,更换字体
menubar.add_cascade(label = "Family", menu = filemenuFamily)
filemenuFamily.add_command(label = "Arial", command = Arial)
filemenuFamily.add_command(label = "Calisto_MT", command = CalistoMT)
filemenuFamily.add_command(label = "微软雅黑", command = MicrosoftYaHei)
# 在About菜单内建立菜单列表,便于查看相关信息
menubar.add_cascade(label = "About", menu = filemenuAbout)
filemenuAbout.add_command(label = "Copyright 版权", command = myCopyright)
filemenuAbout.add_command(label = "Acknowledgement 鸣谢", command = acknowledgement)
filemenuAbout.add_command(label = "Version 版本", command = myVersion)
# 在TimeMode菜单内建立菜单列表,便于切换日间/夜间模式
menubar.add_cascade(label = "Time Mode", menu = filemenuTimeMode)
filemenuTimeMode.add_command(label = "Day Mode 日间模式", command = dayMode)
filemenuTimeMode.add_command(label = "Night Mode 夜间模式", command = nightMode)
# 弹出式菜单(小菜单)部分,便于使用部分编辑功能
popupmenu.add_command(label = "Copy 复制", command = copy)
root.bind("<Control-C>", showPopupMenu)
popupmenu.add_command(label = "Paste 粘贴", command = paste)
root.bind("<Control-V>", showPopupMenu)
popupmenu.add_command(label = "Cut 剪切", command = cut)
root.bind("<Control-X>", showPopupMenu)
popupmenu.add_command(label = "Undo 撤销", command = undo)
root.bind("<Control-Z>", showPopupMenu)
popupmenu.add_command(label = "Redo 复原", command = redo)
root.bind("<Control-Y>", showPopupMenu)
popupmenu.add_separator()
popupmenu.add_command(label = "Minimize 最小化", command = minimize)
root.bind("<Button-3>", showPopupMenu) # 右键打开弹出式菜单
root.config(menu = menubar) # 展示菜单
# 部分快捷键
root.bind("<Control-A>", selectAll)
root.bind("<Control-C>", copy)
root.bind("<Control-V>", paste)
root.bind("<Control-X>", cut)
root.bind("<F6>", search)
root.mainloop()