import os import datetime import multiprocessing import tkinter as tk from tkinter import filedialog from tkinter import messagebox from tkinter import ttk from common.global_analysis import GlobalAnalysis from noa.pilot import PilotAnalysis from down_gui import DownFile import re # 用于正则表达式匹配
last_selected_path = None
def button_set_normal(): app_box.config(state="normal") module_box.config(state="normal") function_box.config(state="normal") start_analysis_btn.config(state="normal") draw_btn.config(state="normal") result_btn.config(state="normal") global_analysis_btn.config(state="disabled") donwload_btn.config(state="normal") app_box.set("行车")
def button_set_disabled(): app_box.config(state="disabled") module_box.config(state="disabled") function_box.config(state="disabled") start_analysis_btn.config(state="disabled") draw_btn.config(state="disabled") result_btn.config(state="disabled") global_analysis_btn.config(state="disabled")
独立的文件夹选择函数,使用options参数确保显示所有文件
def choose_directory(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择record目录',
'mustexist': True,
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
directory = filedialog.askdirectory(**options)
if directory:
last_selected_path = directory # 保存当前选择的路径
label_content.config(text=f"目录: {directory}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
独立的文件选择函数,使用options参数确保显示所有文件
def choose_single_file(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择文件',
'filetypes': [('所有文件', '*.*')],
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
file = filedialog.askopenfilename(**options)
if file:
last_selected_path = os.path.dirname(file) # 保存文件所在目录
label_content.config(text=f"文件: {file}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
def update_gui(func_process, txt_path, result_flag = False): if result_flag: with open(txt_path, 'a') as file: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') file.close() start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag() else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag()
高亮包含*的行
def highlight_lines_with_star(): # 清除之前的高亮 text_box.tag_remove("highlight", "1.0", tk.END)
# 配置高亮标签
text_box.tag_config("highlight", foreground="red")
# 获取文本内容
content = text_box.get("1.0", tk.END)
# 按行分割文本
lines = content.split('\n')
# 遍历每一行,查找包含*的行
for i, line in enumerate(lines):
if '*' in line:
# 计算行的起始和结束位置
start_pos = f"{i+1}.0"
end_pos = f"{i+1}.end"
# 应用高亮标签
text_box.tag_add("highlight", start_pos, end_pos)
根据按钮id调用对应接口
def handle_button_event(draw_flag, result_flag, event_type): now = datetime.datetime.now() time_str = now.strftime('%Y-%m-%d_%H-%M-%S') selected_text = label_content.cget("text")
# 解析路径类型
if selected_text.startswith("目录: "):
record_dir = selected_text[3:].strip()
is_directory = True
if not record_dir.endswith(os.sep):
record_dir += os.sep
elif selected_text.startswith("文件: "):
file_path = selected_text[3:].strip()
is_directory = False
record_dir = os.path.dirname(file_path) # 使用文件所在目录作为分析目录
else:
messagebox.showerror("错误", "未选择有效文件或目录")
start_analysis_btn.config(text = "开始分析")
return
last_dir = os.path.basename(record_dir.rstrip(os.sep))
txt_path = os.path.join(os.path.dirname(record_dir), f"{last_dir}_{time_str}.txt")
text_box.delete(1.0,tk.END) # 清空文本框内容
start_analysis_btn.config(text = "数据分析中...")
func_process = None
if app_box.get() == "行车":
if event_type == "全局分析":
start_analysis_btn.config(text = "开始分析")
global_analysis_btn.config(text = "数据分析中...")
func_process = GlobalAnalysis(progress_queue)
func_process.handle_event_pilot(record_dir, draw_flag)
if event_type == "状态类问题":
func_process = PilotAnalysis(progress_queue)
# 传递文件路径而不是目录
target_path = file_path if not is_directory else record_dir
func_process.handle_downgrade_event(target_path)
if func_process:
root.after(100, update_gui, func_process, txt_path, result_flag)
button_set_disabled()
donwload_btn.config(state="disable")
简化数据结构,只保留行车相关内容
data = { '行车': { '降级': ['状态类问题'], } }
移除下拉框事件绑定函数
def update_appbox(event=None): pass
def update_combobox(event=None): pass
def jira_analysis(comment_flag): print(f"comment_flag={comment_flag}") #broker = DwBroker(user='xu.wenping', password='byd123', env='prd') #jira_obj = JIRA(server=server_addr, auth=('DeepSeek', 'DSIRDird@123456')) #lst, save_file_name = jira_main(args, broker, jira_obj, dw_path_name) # 默认只能查询一个jira #process_info = ProcessorInfo(broker, jira_obj, 1, lst, 0, None, 0, comment_flag, alarm_id, "jira") #start_task_processor(process_info)
def jira_main(): sub_win= tk.Tk() sub_win.title("JIRA分析_"+version) sub_win.geometry("820x600") # 标签 label_title = tk.Label(sub_win, text="JIRA单号:") label_title.place(x=5, y=10) # 下拉框 jira_box = ttk.Combobox(sub_win, state="readonly", width=5, values=["ORIN", "J6M"]) jira_box.set("ORIN") jira_box.place(x=70, y=10) # jira单号文本框 jira_text = tk.Text(sub_win,height=1, width=10) jira_text.place(x=140,y=13) # 创建多选框 comment_flag = tk.BooleanVar() comment_btn = tk.Checkbutton(sub_win, text="是否评论JIRA", variable=comment_flag) comment_btn.place(x=220, y=8) # 创建按钮 global_analysis_btn = tk.Button(sub_win, text="全局分析", command=lambda:jira_analysis(comment_flag.get())) global_analysis_btn.place(x=330, y=4) # 结果输出文本框 text_box = tk.Text(sub_win,height=30, width=100) text_box.place(x=5,y=40,relwidth=0.98,relheight=0.85)
def down_gui(): donwload_btn.config(state="disabled") donw_obj.down_gui(donwload_btn)
def on_closing(): donw_obj.on_sub_window_close(True) # 关闭子UI root.destroy()
if name == "main": version = "1.1.23" # 初始化 multiprocessing.freeze_support() progress_queue = multiprocessing.Queue() # 创建主窗口 root = tk.Tk() # root.title("Sage --for NOA data processing V1.0.5_alpha.2 20250627") root.title("Sage --for NOA data processing V1.0.8_alpha.1 20250723") root.geometry("820x700") # 长*宽
# 创建主菜单
file_menu = tk.Menu(root)
# 创建二级菜单
choose_file_menu = tk.Menu(file_menu, tearoff=0)
choose_file_menu.add_command(label='选择record目录', command=choose_directory)
choose_file_menu.add_command(label='选择单个record', command=choose_single_file)
# 创建一级菜单并绑定二级菜单
file_menu.add_cascade(label='文件', menu=choose_file_menu)
#file_menu.add_command(label='JIRA', command=jira_main)
root.config(menu=file_menu)
# 创建标签
label_title = tk.Label(root, text="record文件/目录:")
label_title.place(x=5, y=0) # 使用place布局,避免布局受其他控件影响
label_content = tk.Label(root, text="No directory selected")
label_content.place(x=115, y=0)
# 创建一级下拉框,设置为disabled状态,固定为"行车"
app_box = ttk.Combobox(root, state="disabled", width=10, values=["行车"])
app_box.place(x=5, y=30)
app_box.set("行车")
# 创建二级下拉框,设置为disabled状态,固定为"降级"
module_box = ttk.Combobox(root, state="disabled", width=10, values=["降级"])
module_box.place(x=110, y=30)
module_box.set("降级")
# 创建三级下拉框,设置为disabled状态,固定为"状态类问题"
function_box = ttk.Combobox(root, state="disabled", width=10, values=["状态类问题"])
function_box.place(x=215, y=30)
function_box.set("状态类问题")
# 创建按钮
start_analysis_btn = tk.Button(root, text="开始分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), function_box.get()))
start_analysis_btn.place(x=320, y=26)
global_analysis_btn = tk.Button(root, text="全局分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), "全局分析"))
global_analysis_btn.config(state=tk.DISABLED)
global_analysis_btn.place(x=410, y=26)
donw_obj = DownFile(label_content, button_set_normal)
donwload_btn = tk.Button(root, text="下载", command=lambda:down_gui())
donwload_btn.place(x=745, y=25)
# 创建多选框
draw_flag = tk.BooleanVar()
draw_btn = tk.Checkbutton(root, text="是否生成规划图", variable=draw_flag)
draw_btn.place(x=495, y=28)
result_flag = tk.BooleanVar()
result_btn = tk.Checkbutton(root, text="是否保存分析结果", variable=result_flag)
result_btn.place(x=605, y=28)
# 创建文本框
text_box = tk.Text(root, height=30, width=100)
text_box.place(x=5, y=70, relwidth=0.98, relheight=0.85)
# 创建纵向滚动条
scrollbar = tk.Scrollbar(text_box, command=text_box.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
text_box.config(yscrollcommand=scrollbar.set)
root.protocol("WM_DELETE_WINDOW", on_closing)
# 未选择文件禁用按钮
if label_content.cget("text") == "No directory selected":
button_set_disabled()
# 启动主循环
root.mainloop()
import os
import datetime import multiprocessing import tkinter as tk from tkinter import filedialog from tkinter import messagebox from tkinter import ttk from common.global_analysis import GlobalAnalysis from noa.pilot import PilotAnalysis from down_gui import DownFile import re # 用于正则表达式匹配
last_selected_path = None
def button_set_normal(): app_box.config(state="normal") module_box.config(state="normal") function_box.config(state="normal") start_analysis_btn.config(state="normal") draw_btn.config(state="normal") result_btn.config(state="normal") global_analysis_btn.config(state="disabled") donwload_btn.config(state="normal") app_box.set("行车")
def button_set_disabled(): app_box.config(state="disabled") module_box.config(state="disabled") function_box.config(state="disabled") start_analysis_btn.config(state="disabled") draw_btn.config(state="disabled") result_btn.config(state="disabled") global_analysis_btn.config(state="disabled")
独立的文件夹选择函数,使用options参数确保显示所有文件
def choose_directory(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择record目录',
'mustexist': True,
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
directory = filedialog.askdirectory(**options)
if directory:
last_selected_path = directory # 保存当前选择的路径
label_content.config(text=f"目录: {directory}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
独立的文件选择函数,使用options参数确保显示所有文件
def choose_single_file(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择文件',
'filetypes': [('所有文件', '*.*')],
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
file = filedialog.askopenfilename(**options)
if file:
last_selected_path = os.path.dirname(file) # 保存文件所在目录
label_content.config(text=f"文件: {file}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
def update_gui(func_process, txt_path, result_flag = False): if result_flag: with open(txt_path, 'a') as file: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') file.close() start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag() else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag()
高亮包含*的行
def highlight_lines_with_star(): # 清除之前的高亮 text_box.tag_remove("highlight", "1.0", tk.END)
# 配置高亮标签
text_box.tag_config("highlight", foreground="red")
# 获取文本内容
content = text_box.get("1.0", tk.END)
# 按行分割文本
lines = content.split('\n')
# 遍历每一行,查找包含*的行
for i, line in enumerate(lines):
if '*' in line:
# 计算行的起始和结束位置
start_pos = f"{i+1}.0"
end_pos = f"{i+1}.end"
# 应用高亮标签
text_box.tag_add("highlight", start_pos, end_pos)
根据按钮id调用对应接口
def handle_button_event(draw_flag, result_flag, event_type): now = datetime.datetime.now() time_str = now.strftime('%Y-%m-%d_%H-%M-%S') selected_text = label_content.cget("text")
# 解析路径类型
if selected_text.startswith("目录: "):
record_dir = selected_text[3:].strip()
is_directory = True
if not record_dir.endswith(os.sep):
record_dir += os.sep
elif selected_text.startswith("文件: "):
file_path = selected_text[3:].strip()
is_directory = False
record_dir = os.path.dirname(file_path) # 使用文件所在目录作为分析目录
else:
messagebox.showerror("错误", "未选择有效文件或目录")
start_analysis_btn.config(text = "开始分析")
return
last_dir = os.path.basename(record_dir.rstrip(os.sep))
txt_path = os.path.join(os.path.dirname(record_dir), f"{last_dir}_{time_str}.txt")
text_box.delete(1.0,tk.END) # 清空文本框内容
start_analysis_btn.config(text = "数据分析中...")
func_process = None
if app_box.get() == "行车":
if event_type == "全局分析":
start_analysis_btn.config(text = "开始分析")
global_analysis_btn.config(text = "数据分析中...")
func_process = GlobalAnalysis(progress_queue)
func_process.handle_event_pilot(record_dir, draw_flag)
if event_type == "状态类问题":
func_process = PilotAnalysis(progress_queue)
# 传递文件路径而不是目录
target_path = file_path if not is_directory else record_dir
func_process.handle_downgrade_event(target_path)
if func_process:
root.after(100, update_gui, func_process, txt_path, result_flag)
button_set_disabled()
donwload_btn.config(state="disable")
简化数据结构,只保留行车相关内容
data = { '行车': { '降级': ['状态类问题'], } }
移除下拉框事件绑定函数
def update_appbox(event=None): pass
def update_combobox(event=None): pass
def jira_analysis(comment_flag): print(f"comment_flag={comment_flag}") #broker = DwBroker(user='xu.wenping', password='byd123', env='prd') #jira_obj = JIRA(server=server_addr, auth=('DeepSeek', 'DSIRDird@123456')) #lst, save_file_name = jira_main(args, broker, jira_obj, dw_path_name) # 默认只能查询一个jira #process_info = ProcessorInfo(broker, jira_obj, 1, lst, 0, None, 0, comment_flag, alarm_id, "jira") #start_task_processor(process_info)
def jira_main(): sub_win= tk.Tk() sub_win.title("JIRA分析_"+version) sub_win.geometry("820x600") # 标签 label_title = tk.Label(sub_win, text="JIRA单号:") label_title.place(x=5, y=10) # 下拉框 jira_box = ttk.Combobox(sub_win, state="readonly", width=5, values=["ORIN", "J6M"]) jira_box.set("ORIN") jira_box.place(x=70, y=10) # jira单号文本框 jira_text = tk.Text(sub_win,height=1, width=10) jira_text.place(x=140,y=13) # 创建多选框 comment_flag = tk.BooleanVar() comment_btn = tk.Checkbutton(sub_win, text="是否评论JIRA", variable=comment_flag) comment_btn.place(x=220, y=8) # 创建按钮 global_analysis_btn = tk.Button(sub_win, text="全局分析", command=lambda:jira_analysis(comment_flag.get())) global_analysis_btn.place(x=330, y=4) # 结果输出文本框 text_box = tk.Text(sub_win,height=30, width=100) text_box.place(x=5,y=40,relwidth=0.98,relheight=0.85)
def down_gui(): donwload_btn.config(state="disabled") donw_obj.down_gui(donwload_btn)
def on_closing(): donw_obj.on_sub_window_close(True) # 关闭子UI root.destroy()
if name == "main": version = "1.1.23" # 初始化 multiprocessing.freeze_support() progress_queue = multiprocessing.Queue() # 创建主窗口 root = tk.Tk() # root.title("Sage --for NOA data processing V1.0.5_alpha.2 20250627") root.title("Sage --for NOA data processing V1.0.8_alpha.1 20250723") root.geometry("820x700") # 长*宽
# 创建主菜单
file_menu = tk.Menu(root)
# 创建二级菜单
choose_file_menu = tk.Menu(file_menu, tearoff=0)
choose_file_menu.add_command(label='选择record目录', command=choose_directory)
choose_file_menu.add_command(label='选择单个record', command=choose_single_file)
# 创建一级菜单并绑定二级菜单
file_menu.add_cascade(label='文件', menu=choose_file_menu)
#file_menu.add_command(label='JIRA', command=jira_main)
root.config(menu=file_menu)
# 创建标签
label_title = tk.Label(root, text="record文件/目录:")
label_title.place(x=5, y=0) # 使用place布局,避免布局受其他控件影响
label_content = tk.Label(root, text="No directory selected")
label_content.place(x=115, y=0)
# 创建一级下拉框,设置为disabled状态,固定为"行车"
app_box = ttk.Combobox(root, state="disabled", width=10, values=["行车"])
app_box.place(x=5, y=30)
app_box.set("行车")
# 创建二级下拉框,设置为disabled状态,固定为"降级"
module_box = ttk.Combobox(root, state="disabled", width=10, values=["降级"])
module_box.place(x=110, y=30)
module_box.set("降级")
# 创建三级下拉框,设置为disabled状态,固定为"状态类问题"
function_box = ttk.Combobox(root, state="disabled", width=10, values=["状态类问题"])
function_box.place(x=215, y=30)
function_box.set("状态类问题")
# 创建按钮
start_analysis_btn = tk.Button(root, text="开始分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), function_box.get()))
start_analysis_btn.place(x=320, y=26)
global_analysis_btn = tk.Button(root, text="全局分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), "全局分析"))
global_analysis_btn.config(state=tk.DISABLED)
global_analysis_btn.place(x=410, y=26)
donw_obj = DownFile(label_content, button_set_normal)
donwload_btn = tk.Button(root, text="下载", command=lambda:down_gui())
donwload_btn.place(x=745, y=25)
# 创建多选框
draw_flag = tk.BooleanVar()
draw_btn = tk.Checkbutton(root, text="是否生成规划图", variable=draw_flag)
draw_btn.place(x=495, y=28)
result_flag = tk.BooleanVar()
result_btn = tk.Checkbutton(root, text="是否保存分析结果", variable=result_flag)
result_btn.place(x=605, y=28)
# 创建文本框
text_box = tk.Text(root, height=30, width=100)
text_box.place(x=5, y=70, relwidth=0.98, relheight=0.85)
# 创建纵向滚动条
scrollbar = tk.Scrollbar(text_box, command=text_box.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
text_box.config(yscrollcommand=scrollbar.set)
root.protocol("WM_DELETE_WINDOW", on_closing)
# 未选择文件禁用按钮
if label_content.cget("text") == "No directory selected":
button_set_disabled()
# 启动主循环
root.mainloop()
import os
import datetime import multiprocessing import tkinter as tk from tkinter import filedialog from tkinter import messagebox from tkinter import ttk from common.global_analysis import GlobalAnalysis from noa.pilot import PilotAnalysis from down_gui import DownFile import re # 用于正则表达式匹配
last_selected_path = None
def button_set_normal(): app_box.config(state="normal") module_box.config(state="normal") function_box.config(state="normal") start_analysis_btn.config(state="normal") draw_btn.config(state="normal") result_btn.config(state="normal") global_analysis_btn.config(state="disabled") donwload_btn.config(state="normal") app_box.set("行车")
def button_set_disabled(): app_box.config(state="disabled") module_box.config(state="disabled") function_box.config(state="disabled") start_analysis_btn.config(state="disabled") draw_btn.config(state="disabled") result_btn.config(state="disabled") global_analysis_btn.config(state="disabled")
独立的文件夹选择函数,使用options参数确保显示所有文件
def choose_directory(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择record目录',
'mustexist': True,
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
directory = filedialog.askdirectory(**options)
if directory:
last_selected_path = directory # 保存当前选择的路径
label_content.config(text=f"目录: {directory}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
独立的文件选择函数,使用options参数确保显示所有文件
def choose_single_file(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择文件',
'filetypes': [('所有文件', '*.*')],
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
file = filedialog.askopenfilename(**options)
if file:
last_selected_path = os.path.dirname(file) # 保存文件所在目录
label_content.config(text=f"文件: {file}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
def update_gui(func_process, txt_path, result_flag = False): if result_flag: with open(txt_path, 'a') as file: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') file.close() start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag() else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag()
高亮包含*的行
def highlight_lines_with_star(): # 清除之前的高亮 text_box.tag_remove("highlight", "1.0", tk.END)
# 配置高亮标签
text_box.tag_config("highlight", foreground="red")
# 获取文本内容
content = text_box.get("1.0", tk.END)
# 按行分割文本
lines = content.split('\n')
# 遍历每一行,查找包含*的行
for i, line in enumerate(lines):
if '*' in line:
# 计算行的起始和结束位置
start_pos = f"{i+1}.0"
end_pos = f"{i+1}.end"
# 应用高亮标签
text_box.tag_add("highlight", start_pos, end_pos)
根据按钮id调用对应接口
def handle_button_event(draw_flag, result_flag, event_type): now = datetime.datetime.now() time_str = now.strftime('%Y-%m-%d_%H-%M-%S') selected_text = label_content.cget("text")
# 解析路径类型
if selected_text.startswith("目录: "):
record_dir = selected_text[3:].strip()
is_directory = True
if not record_dir.endswith(os.sep):
record_dir += os.sep
elif selected_text.startswith("文件: "):
file_path = selected_text[3:].strip()
is_directory = False
record_dir = os.path.dirname(file_path) # 使用文件所在目录作为分析目录
else:
messagebox.showerror("错误", "未选择有效文件或目录")
start_analysis_btn.config(text = "开始分析")
return
last_dir = os.path.basename(record_dir.rstrip(os.sep))
txt_path = os.path.join(os.path.dirname(record_dir), f"{last_dir}_{time_str}.txt")
text_box.delete(1.0,tk.END) # 清空文本框内容
start_analysis_btn.config(text = "数据分析中...")
func_process = None
if app_box.get() == "行车":
if event_type == "全局分析":
start_analysis_btn.config(text = "开始分析")
global_analysis_btn.config(text = "数据分析中...")
func_process = GlobalAnalysis(progress_queue)
func_process.handle_event_pilot(record_dir, draw_flag)
if event_type == "状态类问题":
func_process = PilotAnalysis(progress_queue)
# 传递文件路径而不是目录
target_path = file_path if not is_directory else record_dir
func_process.handle_downgrade_event(target_path)
if func_process:
root.after(100, update_gui, func_process, txt_path, result_flag)
button_set_disabled()
donwload_btn.config(state="disable")
简化数据结构,只保留行车相关内容
data = { '行车': { '降级': ['状态类问题'], } }
移除下拉框事件绑定函数
def update_appbox(event=None): pass
def update_combobox(event=None): pass
def jira_analysis(comment_flag): print(f"comment_flag={comment_flag}") #broker = DwBroker(user='xu.wenping', password='byd123', env='prd') #jira_obj = JIRA(server=server_addr, auth=('DeepSeek', 'DSIRDird@123456')) #lst, save_file_name = jira_main(args, broker, jira_obj, dw_path_name) # 默认只能查询一个jira #process_info = ProcessorInfo(broker, jira_obj, 1, lst, 0, None, 0, comment_flag, alarm_id, "jira") #start_task_processor(process_info)
def jira_main(): sub_win= tk.Tk() sub_win.title("JIRA分析_"+version) sub_win.geometry("820x600") # 标签 label_title = tk.Label(sub_win, text="JIRA单号:") label_title.place(x=5, y=10) # 下拉框 jira_box = ttk.Combobox(sub_win, state="readonly", width=5, values=["ORIN", "J6M"]) jira_box.set("ORIN") jira_box.place(x=70, y=10) # jira单号文本框 jira_text = tk.Text(sub_win,height=1, width=10) jira_text.place(x=140,y=13) # 创建多选框 comment_flag = tk.BooleanVar() comment_btn = tk.Checkbutton(sub_win, text="是否评论JIRA", variable=comment_flag) comment_btn.place(x=220, y=8) # 创建按钮 global_analysis_btn = tk.Button(sub_win, text="全局分析", command=lambda:jira_analysis(comment_flag.get())) global_analysis_btn.place(x=330, y=4) # 结果输出文本框 text_box = tk.Text(sub_win,height=30, width=100) text_box.place(x=5,y=40,relwidth=0.98,relheight=0.85)
def down_gui(): donwload_btn.config(state="disabled") donw_obj.down_gui(donwload_btn)
def on_closing(): donw_obj.on_sub_window_close(True) # 关闭子UI root.destroy()
if name == "main": version = "1.1.23" # 初始化 multiprocessing.freeze_support() progress_queue = multiprocessing.Queue() # 创建主窗口 root = tk.Tk() # root.title("Sage --for NOA data processing V1.0.5_alpha.2 20250627") root.title("Sage --for NOA data processing V1.0.8_alpha.1 20250723") root.geometry("820x700") # 长*宽
# 创建主菜单
file_menu = tk.Menu(root)
# 创建二级菜单
choose_file_menu = tk.Menu(file_menu, tearoff=0)
choose_file_menu.add_command(label='选择record目录', command=choose_directory)
choose_file_menu.add_command(label='选择单个record', command=choose_single_file)
# 创建一级菜单并绑定二级菜单
file_menu.add_cascade(label='文件', menu=choose_file_menu)
#file_menu.add_command(label='JIRA', command=jira_main)
root.config(menu=file_menu)
# 创建标签
label_title = tk.Label(root, text="record文件/目录:")
label_title.place(x=5, y=0) # 使用place布局,避免布局受其他控件影响
label_content = tk.Label(root, text="No directory selected")
label_content.place(x=115, y=0)
# 创建一级下拉框,设置为disabled状态,固定为"行车"
app_box = ttk.Combobox(root, state="disabled", width=10, values=["行车"])
app_box.place(x=5, y=30)
app_box.set("行车")
# 创建二级下拉框,设置为disabled状态,固定为"降级"
module_box = ttk.Combobox(root, state="disabled", width=10, values=["降级"])
module_box.place(x=110, y=30)
module_box.set("降级")
# 创建三级下拉框,设置为disabled状态,固定为"状态类问题"
function_box = ttk.Combobox(root, state="disabled", width=10, values=["状态类问题"])
function_box.place(x=215, y=30)
function_box.set("状态类问题")
# 创建按钮
start_analysis_btn = tk.Button(root, text="开始分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), function_box.get()))
start_analysis_btn.place(x=320, y=26)
global_analysis_btn = tk.Button(root, text="全局分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), "全局分析"))
global_analysis_btn.config(state=tk.DISABLED)
global_analysis_btn.place(x=410, y=26)
donw_obj = DownFile(label_content, button_set_normal)
donwload_btn = tk.Button(root, text="下载", command=lambda:down_gui())
donwload_btn.place(x=745, y=25)
# 创建多选框
draw_flag = tk.BooleanVar()
draw_btn = tk.Checkbutton(root, text="是否生成规划图", variable=draw_flag)
draw_btn.place(x=495, y=28)
result_flag = tk.BooleanVar()
result_btn = tk.Checkbutton(root, text="是否保存分析结果", variable=result_flag)
result_btn.place(x=605, y=28)
# 创建文本框
text_box = tk.Text(root, height=30, width=100)
text_box.place(x=5, y=70, relwidth=0.98, relheight=0.85)
# 创建纵向滚动条
scrollbar = tk.Scrollbar(text_box, command=text_box.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
text_box.config(yscrollcommand=scrollbar.set)
root.protocol("WM_DELETE_WINDOW", on_closing)
# 未选择文件禁用按钮
if label_content.cget("text") == "No directory selected":
button_set_disabled()
# 启动主循环
root.mainloop()
import os
import datetime import multiprocessing import tkinter as tk from tkinter import filedialog from tkinter import messagebox from tkinter import ttk from common.global_analysis import GlobalAnalysis from noa.pilot import PilotAnalysis from down_gui import DownFile import re # 用于正则表达式匹配
last_selected_path = None
def button_set_normal(): app_box.config(state="normal") module_box.config(state="normal") function_box.config(state="normal") start_analysis_btn.config(state="normal") draw_btn.config(state="normal") result_btn.config(state="normal") global_analysis_btn.config(state="disabled") donwload_btn.config(state="normal") app_box.set("行车")
def button_set_disabled(): app_box.config(state="disabled") module_box.config(state="disabled") function_box.config(state="disabled") start_analysis_btn.config(state="disabled") draw_btn.config(state="disabled") result_btn.config(state="disabled") global_analysis_btn.config(state="disabled")
独立的文件夹选择函数,使用options参数确保显示所有文件
def choose_directory(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择record目录',
'mustexist': True,
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
directory = filedialog.askdirectory(**options)
if directory:
last_selected_path = directory # 保存当前选择的路径
label_content.config(text=f"目录: {directory}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
独立的文件选择函数,使用options参数确保显示所有文件
def choose_single_file(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择文件',
'filetypes': [('所有文件', '*.*')],
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
file = filedialog.askopenfilename(**options)
if file:
last_selected_path = os.path.dirname(file) # 保存文件所在目录
label_content.config(text=f"文件: {file}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
def update_gui(func_process, txt_path, result_flag = False): if result_flag: with open(txt_path, 'a') as file: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') file.close() start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag() else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag()
高亮包含*的行
def highlight_lines_with_star(): # 清除之前的高亮 text_box.tag_remove("highlight", "1.0", tk.END)
# 配置高亮标签
text_box.tag_config("highlight", foreground="red")
# 获取文本内容
content = text_box.get("1.0", tk.END)
# 按行分割文本
lines = content.split('\n')
# 遍历每一行,查找包含*的行
for i, line in enumerate(lines):
if '*' in line:
# 计算行的起始和结束位置
start_pos = f"{i+1}.0"
end_pos = f"{i+1}.end"
# 应用高亮标签
text_box.tag_add("highlight", start_pos, end_pos)
根据按钮id调用对应接口
def handle_button_event(draw_flag, result_flag, event_type): now = datetime.datetime.now() time_str = now.strftime('%Y-%m-%d_%H-%M-%S') selected_text = label_content.cget("text")
# 解析路径类型
if selected_text.startswith("目录: "):
record_dir = selected_text[3:].strip()
is_directory = True
if not record_dir.endswith(os.sep):
record_dir += os.sep
elif selected_text.startswith("文件: "):
file_path = selected_text[3:].strip()
is_directory = False
record_dir = os.path.dirname(file_path) # 使用文件所在目录作为分析目录
else:
messagebox.showerror("错误", "未选择有效文件或目录")
start_analysis_btn.config(text = "开始分析")
return
last_dir = os.path.basename(record_dir.rstrip(os.sep))
txt_path = os.path.join(os.path.dirname(record_dir), f"{last_dir}_{time_str}.txt")
text_box.delete(1.0,tk.END) # 清空文本框内容
start_analysis_btn.config(text = "数据分析中...")
func_process = None
if app_box.get() == "行车":
if event_type == "全局分析":
start_analysis_btn.config(text = "开始分析")
global_analysis_btn.config(text = "数据分析中...")
func_process = GlobalAnalysis(progress_queue)
func_process.handle_event_pilot(record_dir, draw_flag)
if event_type == "状态类问题":
func_process = PilotAnalysis(progress_queue)
# 传递文件路径而不是目录
target_path = file_path if not is_directory else record_dir
func_process.handle_downgrade_event(target_path)
if func_process:
root.after(100, update_gui, func_process, txt_path, result_flag)
button_set_disabled()
donwload_btn.config(state="disable")
简化数据结构,只保留行车相关内容
data = { '行车': { '降级': ['状态类问题'], } }
移除下拉框事件绑定函数
def update_appbox(event=None): pass
def update_combobox(event=None): pass
def jira_analysis(comment_flag): print(f"comment_flag={comment_flag}") #broker = DwBroker(user='xu.wenping', password='byd123', env='prd') #jira_obj = JIRA(server=server_addr, auth=('DeepSeek', 'DSIRDird@123456')) #lst, save_file_name = jira_main(args, broker, jira_obj, dw_path_name) # 默认只能查询一个jira #process_info = ProcessorInfo(broker, jira_obj, 1, lst, 0, None, 0, comment_flag, alarm_id, "jira") #start_task_processor(process_info)
def jira_main(): sub_win= tk.Tk() sub_win.title("JIRA分析_"+version) sub_win.geometry("820x600") # 标签 label_title = tk.Label(sub_win, text="JIRA单号:") label_title.place(x=5, y=10) # 下拉框 jira_box = ttk.Combobox(sub_win, state="readonly", width=5, values=["ORIN", "J6M"]) jira_box.set("ORIN") jira_box.place(x=70, y=10) # jira单号文本框 jira_text = tk.Text(sub_win,height=1, width=10) jira_text.place(x=140,y=13) # 创建多选框 comment_flag = tk.BooleanVar() comment_btn = tk.Checkbutton(sub_win, text="是否评论JIRA", variable=comment_flag) comment_btn.place(x=220, y=8) # 创建按钮 global_analysis_btn = tk.Button(sub_win, text="全局分析", command=lambda:jira_analysis(comment_flag.get())) global_analysis_btn.place(x=330, y=4) # 结果输出文本框 text_box = tk.Text(sub_win,height=30, width=100) text_box.place(x=5,y=40,relwidth=0.98,relheight=0.85)
def down_gui(): donwload_btn.config(state="disabled") donw_obj.down_gui(donwload_btn)
def on_closing(): donw_obj.on_sub_window_close(True) # 关闭子UI root.destroy()
if name == "main": version = "1.1.23" # 初始化 multiprocessing.freeze_support() progress_queue = multiprocessing.Queue() # 创建主窗口 root = tk.Tk() # root.title("Sage --for NOA data processing V1.0.5_alpha.2 20250627") root.title("Sage --for NOA data processing V1.0.8_alpha.1 20250723") root.geometry("820x700") # 长*宽
# 创建主菜单
file_menu = tk.Menu(root)
# 创建二级菜单
choose_file_menu = tk.Menu(file_menu, tearoff=0)
choose_file_menu.add_command(label='选择record目录', command=choose_directory)
choose_file_menu.add_command(label='选择单个record', command=choose_single_file)
# 创建一级菜单并绑定二级菜单
file_menu.add_cascade(label='文件', menu=choose_file_menu)
#file_menu.add_command(label='JIRA', command=jira_main)
root.config(menu=file_menu)
# 创建标签
label_title = tk.Label(root, text="record文件/目录:")
label_title.place(x=5, y=0) # 使用place布局,避免布局受其他控件影响
label_content = tk.Label(root, text="No directory selected")
label_content.place(x=115, y=0)
# 创建一级下拉框,设置为disabled状态,固定为"行车"
app_box = ttk.Combobox(root, state="disabled", width=10, values=["行车"])
app_box.place(x=5, y=30)
app_box.set("行车")
# 创建二级下拉框,设置为disabled状态,固定为"降级"
module_box = ttk.Combobox(root, state="disabled", width=10, values=["降级"])
module_box.place(x=110, y=30)
module_box.set("降级")
# 创建三级下拉框,设置为disabled状态,固定为"状态类问题"
function_box = ttk.Combobox(root, state="disabled", width=10, values=["状态类问题"])
function_box.place(x=215, y=30)
function_box.set("状态类问题")
# 创建按钮
start_analysis_btn = tk.Button(root, text="开始分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), function_box.get()))
start_analysis_btn.place(x=320, y=26)
global_analysis_btn = tk.Button(root, text="全局分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), "全局分析"))
global_analysis_btn.config(state=tk.DISABLED)
global_analysis_btn.place(x=410, y=26)
donw_obj = DownFile(label_content, button_set_normal)
donwload_btn = tk.Button(root, text="下载", command=lambda:down_gui())
donwload_btn.place(x=745, y=25)
# 创建多选框
draw_flag = tk.BooleanVar()
draw_btn = tk.Checkbutton(root, text="是否生成规划图", variable=draw_flag)
draw_btn.place(x=495, y=28)
result_flag = tk.BooleanVar()
result_btn = tk.Checkbutton(root, text="是否保存分析结果", variable=result_flag)
result_btn.place(x=605, y=28)
# 创建文本框
text_box = tk.Text(root, height=30, width=100)
text_box.place(x=5, y=70, relwidth=0.98, relheight=0.85)
# 创建纵向滚动条
scrollbar = tk.Scrollbar(text_box, command=text_box.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
text_box.config(yscrollcommand=scrollbar.set)
root.protocol("WM_DELETE_WINDOW", on_closing)
# 未选择文件禁用按钮
if label_content.cget("text") == "No directory selected":
button_set_disabled()
# 启动主循环
root.mainloop()
import os
import datetime import multiprocessing import tkinter as tk from tkinter import filedialog from tkinter import messagebox from tkinter import ttk from common.global_analysis import GlobalAnalysis from noa.pilot import PilotAnalysis from down_gui import DownFile import re # 用于正则表达式匹配
last_selected_path = None
def button_set_normal(): app_box.config(state="normal") module_box.config(state="normal") function_box.config(state="normal") start_analysis_btn.config(state="normal") draw_btn.config(state="normal") result_btn.config(state="normal") global_analysis_btn.config(state="disabled") donwload_btn.config(state="normal") app_box.set("行车")
def button_set_disabled(): app_box.config(state="disabled") module_box.config(state="disabled") function_box.config(state="disabled") start_analysis_btn.config(state="disabled") draw_btn.config(state="disabled") result_btn.config(state="disabled") global_analysis_btn.config(state="disabled")
独立的文件夹选择函数,使用options参数确保显示所有文件
def choose_directory(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择record目录',
'mustexist': True,
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
directory = filedialog.askdirectory(**options)
if directory:
last_selected_path = directory # 保存当前选择的路径
label_content.config(text=f"目录: {directory}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
独立的文件选择函数,使用options参数确保显示所有文件
def choose_single_file(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择文件',
'filetypes': [('所有文件', '*.*')],
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
file = filedialog.askopenfilename(**options)
if file:
last_selected_path = os.path.dirname(file) # 保存文件所在目录
label_content.config(text=f"文件: {file}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
def update_gui(func_process, txt_path, result_flag = False): if result_flag: with open(txt_path, 'a') as file: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') file.close() start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag() else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag()
高亮包含*的行
def highlight_lines_with_star(): # 清除之前的高亮 text_box.tag_remove("highlight", "1.0", tk.END)
# 配置高亮标签
text_box.tag_config("highlight", foreground="red")
# 获取文本内容
content = text_box.get("1.0", tk.END)
# 按行分割文本
lines = content.split('\n')
# 遍历每一行,查找包含*的行
for i, line in enumerate(lines):
if '*' in line:
# 计算行的起始和结束位置
start_pos = f"{i+1}.0"
end_pos = f"{i+1}.end"
# 应用高亮标签
text_box.tag_add("highlight", start_pos, end_pos)
根据按钮id调用对应接口
def handle_button_event(draw_flag, result_flag, event_type): now = datetime.datetime.now() time_str = now.strftime('%Y-%m-%d_%H-%M-%S') selected_text = label_content.cget("text")
# 解析路径类型
if selected_text.startswith("目录: "):
record_dir = selected_text[3:].strip()
is_directory = True
if not record_dir.endswith(os.sep):
record_dir += os.sep
elif selected_text.startswith("文件: "):
file_path = selected_text[3:].strip()
is_directory = False
record_dir = os.path.dirname(file_path) # 使用文件所在目录作为分析目录
else:
messagebox.showerror("错误", "未选择有效文件或目录")
start_analysis_btn.config(text = "开始分析")
return
last_dir = os.path.basename(record_dir.rstrip(os.sep))
txt_path = os.path.join(os.path.dirname(record_dir), f"{last_dir}_{time_str}.txt")
text_box.delete(1.0,tk.END) # 清空文本框内容
start_analysis_btn.config(text = "数据分析中...")
func_process = None
if app_box.get() == "行车":
if event_type == "全局分析":
start_analysis_btn.config(text = "开始分析")
global_analysis_btn.config(text = "数据分析中...")
func_process = GlobalAnalysis(progress_queue)
func_process.handle_event_pilot(record_dir, draw_flag)
if event_type == "状态类问题":
func_process = PilotAnalysis(progress_queue)
# 传递文件路径而不是目录
target_path = file_path if not is_directory else record_dir
func_process.handle_downgrade_event(target_path)
if func_process:
root.after(100, update_gui, func_process, txt_path, result_flag)
button_set_disabled()
donwload_btn.config(state="disable")
简化数据结构,只保留行车相关内容
data = { '行车': { '降级': ['状态类问题'], } }
移除下拉框事件绑定函数
def update_appbox(event=None): pass
def update_combobox(event=None): pass
def jira_analysis(comment_flag): print(f"comment_flag={comment_flag}") #broker = DwBroker(user='xu.wenping', password='byd123', env='prd') #jira_obj = JIRA(server=server_addr, auth=('DeepSeek', 'DSIRDird@123456')) #lst, save_file_name = jira_main(args, broker, jira_obj, dw_path_name) # 默认只能查询一个jira #process_info = ProcessorInfo(broker, jira_obj, 1, lst, 0, None, 0, comment_flag, alarm_id, "jira") #start_task_processor(process_info)
def jira_main(): sub_win= tk.Tk() sub_win.title("JIRA分析_"+version) sub_win.geometry("820x600") # 标签 label_title = tk.Label(sub_win, text="JIRA单号:") label_title.place(x=5, y=10) # 下拉框 jira_box = ttk.Combobox(sub_win, state="readonly", width=5, values=["ORIN", "J6M"]) jira_box.set("ORIN") jira_box.place(x=70, y=10) # jira单号文本框 jira_text = tk.Text(sub_win,height=1, width=10) jira_text.place(x=140,y=13) # 创建多选框 comment_flag = tk.BooleanVar() comment_btn = tk.Checkbutton(sub_win, text="是否评论JIRA", variable=comment_flag) comment_btn.place(x=220, y=8) # 创建按钮 global_analysis_btn = tk.Button(sub_win, text="全局分析", command=lambda:jira_analysis(comment_flag.get())) global_analysis_btn.place(x=330, y=4) # 结果输出文本框 text_box = tk.Text(sub_win,height=30, width=100) text_box.place(x=5,y=40,relwidth=0.98,relheight=0.85)
def down_gui(): donwload_btn.config(state="disabled") donw_obj.down_gui(donwload_btn)
def on_closing(): donw_obj.on_sub_window_close(True) # 关闭子UI root.destroy()
if name == "main": version = "1.1.23" # 初始化 multiprocessing.freeze_support() progress_queue = multiprocessing.Queue() # 创建主窗口 root = tk.Tk() # root.title("Sage --for NOA data processing V1.0.5_alpha.2 20250627") root.title("Sage --for NOA data processing V1.0.8_alpha.1 20250723") root.geometry("820x700") # 长*宽
# 创建主菜单
file_menu = tk.Menu(root)
# 创建二级菜单
choose_file_menu = tk.Menu(file_menu, tearoff=0)
choose_file_menu.add_command(label='选择record目录', command=choose_directory)
choose_file_menu.add_command(label='选择单个record', command=choose_single_file)
# 创建一级菜单并绑定二级菜单
file_menu.add_cascade(label='文件', menu=choose_file_menu)
#file_menu.add_command(label='JIRA', command=jira_main)
root.config(menu=file_menu)
# 创建标签
label_title = tk.Label(root, text="record文件/目录:")
label_title.place(x=5, y=0) # 使用place布局,避免布局受其他控件影响
label_content = tk.Label(root, text="No directory selected")
label_content.place(x=115, y=0)
# 创建一级下拉框,设置为disabled状态,固定为"行车"
app_box = ttk.Combobox(root, state="disabled", width=10, values=["行车"])
app_box.place(x=5, y=30)
app_box.set("行车")
# 创建二级下拉框,设置为disabled状态,固定为"降级"
module_box = ttk.Combobox(root, state="disabled", width=10, values=["降级"])
module_box.place(x=110, y=30)
module_box.set("降级")
# 创建三级下拉框,设置为disabled状态,固定为"状态类问题"
function_box = ttk.Combobox(root, state="disabled", width=10, values=["状态类问题"])
function_box.place(x=215, y=30)
function_box.set("状态类问题")
# 创建按钮
start_analysis_btn = tk.Button(root, text="开始分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), function_box.get()))
start_analysis_btn.place(x=320, y=26)
global_analysis_btn = tk.Button(root, text="全局分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), "全局分析"))
global_analysis_btn.config(state=tk.DISABLED)
global_analysis_btn.place(x=410, y=26)
donw_obj = DownFile(label_content, button_set_normal)
donwload_btn = tk.Button(root, text="下载", command=lambda:down_gui())
donwload_btn.place(x=745, y=25)
# 创建多选框
draw_flag = tk.BooleanVar()
draw_btn = tk.Checkbutton(root, text="是否生成规划图", variable=draw_flag)
draw_btn.place(x=495, y=28)
result_flag = tk.BooleanVar()
result_btn = tk.Checkbutton(root, text="是否保存分析结果", variable=result_flag)
result_btn.place(x=605, y=28)
# 创建文本框
text_box = tk.Text(root, height=30, width=100)
text_box.place(x=5, y=70, relwidth=0.98, relheight=0.85)
# 创建纵向滚动条
scrollbar = tk.Scrollbar(text_box, command=text_box.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
text_box.config(yscrollcommand=scrollbar.set)
root.protocol("WM_DELETE_WINDOW", on_closing)
# 未选择文件禁用按钮
if label_content.cget("text") == "No directory selected":
button_set_disabled()
# 启动主循环
root.mainloop()
import os
import datetime import multiprocessing import tkinter as tk from tkinter import filedialog from tkinter import messagebox from tkinter import ttk from common.global_analysis import GlobalAnalysis from noa.pilot import PilotAnalysis from down_gui import DownFile import re # 用于正则表达式匹配
last_selected_path = None
def button_set_normal(): app_box.config(state="normal") module_box.config(state="normal") function_box.config(state="normal") start_analysis_btn.config(state="normal") draw_btn.config(state="normal") result_btn.config(state="normal") global_analysis_btn.config(state="disabled") donwload_btn.config(state="normal") app_box.set("行车")
def button_set_disabled(): app_box.config(state="disabled") module_box.config(state="disabled") function_box.config(state="disabled") start_analysis_btn.config(state="disabled") draw_btn.config(state="disabled") result_btn.config(state="disabled") global_analysis_btn.config(state="disabled")
独立的文件夹选择函数,使用options参数确保显示所有文件
def choose_directory(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择record目录',
'mustexist': True,
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
directory = filedialog.askdirectory(**options)
if directory:
last_selected_path = directory # 保存当前选择的路径
label_content.config(text=f"目录: {directory}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
独立的文件选择函数,使用options参数确保显示所有文件
def choose_single_file(): global last_selected_path
# 设置文件对话框选项
options = {
'title': '选择文件',
'filetypes': [('所有文件', '*.*')],
}
# 如果有上次选择的路径,设置为初始目录
if last_selected_path and os.path.exists(last_selected_path):
options['initialdir'] = last_selected_path
file = filedialog.askopenfilename(**options)
if file:
last_selected_path = os.path.dirname(file) # 保存文件所在目录
label_content.config(text=f"文件: {file}")
button_set_normal()
# 保持默认值
app_box.set("行车")
module_box.set("降级")
function_box.set("状态类问题")
def update_gui(func_process, txt_path, result_flag = False): if result_flag: with open(txt_path, 'a') as file: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) file.write(progress + '\n') file.close() start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag() else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) if not func_process.is_done(): root.after(100, update_gui, func_process, txt_path, result_flag) else: while not progress_queue.empty(): progress = progress_queue.get() text_box.insert(tk.END, progress + '\n') highlight_lines_with_star() # 高亮包含的行 text_box.yview(tk.END) start_analysis_btn.config(text = "开始分析") button_set_normal() func_process.revert_done_flag()
高亮包含*的行
def highlight_lines_with_star(): # 清除之前的高亮 text_box.tag_remove("highlight", "1.0", tk.END)
# 配置高亮标签
text_box.tag_config("highlight", foreground="red")
# 获取文本内容
content = text_box.get("1.0", tk.END)
# 按行分割文本
lines = content.split('\n')
# 遍历每一行,查找包含*的行
for i, line in enumerate(lines):
if '*' in line:
# 计算行的起始和结束位置
start_pos = f"{i+1}.0"
end_pos = f"{i+1}.end"
# 应用高亮标签
text_box.tag_add("highlight", start_pos, end_pos)
根据按钮id调用对应接口
def handle_button_event(draw_flag, result_flag, event_type): now = datetime.datetime.now() time_str = now.strftime('%Y-%m-%d_%H-%M-%S') selected_text = label_content.cget("text")
# 解析路径类型
if selected_text.startswith("目录: "):
record_dir = selected_text[3:].strip()
is_directory = True
if not record_dir.endswith(os.sep):
record_dir += os.sep
elif selected_text.startswith("文件: "):
file_path = selected_text[3:].strip()
is_directory = False
record_dir = os.path.dirname(file_path) # 使用文件所在目录作为分析目录
else:
messagebox.showerror("错误", "未选择有效文件或目录")
start_analysis_btn.config(text = "开始分析")
return
last_dir = os.path.basename(record_dir.rstrip(os.sep))
txt_path = os.path.join(os.path.dirname(record_dir), f"{last_dir}_{time_str}.txt")
text_box.delete(1.0,tk.END) # 清空文本框内容
start_analysis_btn.config(text = "数据分析中...")
func_process = None
if app_box.get() == "行车":
if event_type == "全局分析":
start_analysis_btn.config(text = "开始分析")
global_analysis_btn.config(text = "数据分析中...")
func_process = GlobalAnalysis(progress_queue)
func_process.handle_event_pilot(record_dir, draw_flag)
if event_type == "状态类问题":
func_process = PilotAnalysis(progress_queue)
# 传递文件路径而不是目录
target_path = file_path if not is_directory else record_dir
func_process.handle_downgrade_event(target_path)
if func_process:
root.after(100, update_gui, func_process, txt_path, result_flag)
button_set_disabled()
donwload_btn.config(state="disable")
简化数据结构,只保留行车相关内容
data = { '行车': { '降级': ['状态类问题'], } }
移除下拉框事件绑定函数
def update_appbox(event=None): pass
def update_combobox(event=None): pass
def jira_analysis(comment_flag): print(f"comment_flag={comment_flag}") #broker = DwBroker(user='xu.wenping', password='byd123', env='prd') #jira_obj = JIRA(server=server_addr, auth=('DeepSeek', 'DSIRDird@123456')) #lst, save_file_name = jira_main(args, broker, jira_obj, dw_path_name) # 默认只能查询一个jira #process_info = ProcessorInfo(broker, jira_obj, 1, lst, 0, None, 0, comment_flag, alarm_id, "jira") #start_task_processor(process_info)
def jira_main(): sub_win= tk.Tk() sub_win.title("JIRA分析_"+version) sub_win.geometry("820x600") # 标签 label_title = tk.Label(sub_win, text="JIRA单号:") label_title.place(x=5, y=10) # 下拉框 jira_box = ttk.Combobox(sub_win, state="readonly", width=5, values=["ORIN", "J6M"]) jira_box.set("ORIN") jira_box.place(x=70, y=10) # jira单号文本框 jira_text = tk.Text(sub_win,height=1, width=10) jira_text.place(x=140,y=13) # 创建多选框 comment_flag = tk.BooleanVar() comment_btn = tk.Checkbutton(sub_win, text="是否评论JIRA", variable=comment_flag) comment_btn.place(x=220, y=8) # 创建按钮 global_analysis_btn = tk.Button(sub_win, text="全局分析", command=lambda:jira_analysis(comment_flag.get())) global_analysis_btn.place(x=330, y=4) # 结果输出文本框 text_box = tk.Text(sub_win,height=30, width=100) text_box.place(x=5,y=40,relwidth=0.98,relheight=0.85)
def down_gui(): donwload_btn.config(state="disabled") donw_obj.down_gui(donwload_btn)
def on_closing(): donw_obj.on_sub_window_close(True) # 关闭子UI root.destroy()
if name == "main": version = "1.1.23" # 初始化 multiprocessing.freeze_support() progress_queue = multiprocessing.Queue() # 创建主窗口 root = tk.Tk() # root.title("Sage --for NOA data processing V1.0.5_alpha.2 20250627") root.title("Sage --for NOA data processing V1.0.8_alpha.1 20250723") root.geometry("820x700") # 长*宽
# 创建主菜单
file_menu = tk.Menu(root)
# 创建二级菜单
choose_file_menu = tk.Menu(file_menu, tearoff=0)
choose_file_menu.add_command(label='选择record目录', command=choose_directory)
choose_file_menu.add_command(label='选择单个record', command=choose_single_file)
# 创建一级菜单并绑定二级菜单
file_menu.add_cascade(label='文件', menu=choose_file_menu)
#file_menu.add_command(label='JIRA', command=jira_main)
root.config(menu=file_menu)
# 创建标签
label_title = tk.Label(root, text="record文件/目录:")
label_title.place(x=5, y=0) # 使用place布局,避免布局受其他控件影响
label_content = tk.Label(root, text="No directory selected")
label_content.place(x=115, y=0)
# 创建一级下拉框,设置为disabled状态,固定为"行车"
app_box = ttk.Combobox(root, state="disabled", width=10, values=["行车"])
app_box.place(x=5, y=30)
app_box.set("行车")
# 创建二级下拉框,设置为disabled状态,固定为"降级"
module_box = ttk.Combobox(root, state="disabled", width=10, values=["降级"])
module_box.place(x=110, y=30)
module_box.set("降级")
# 创建三级下拉框,设置为disabled状态,固定为"状态类问题"
function_box = ttk.Combobox(root, state="disabled", width=10, values=["状态类问题"])
function_box.place(x=215, y=30)
function_box.set("状态类问题")
# 创建按钮
start_analysis_btn = tk.Button(root, text="开始分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), function_box.get()))
start_analysis_btn.place(x=320, y=26)
global_analysis_btn = tk.Button(root, text="全局分析", command=lambda:handle_button_event(draw_flag.get(), result_flag.get(), "全局分析"))
global_analysis_btn.config(state=tk.DISABLED)
global_analysis_btn.place(x=410, y=26)
donw_obj = DownFile(label_content, button_set_normal)
donwload_btn = tk.Button(root, text="下载", command=lambda:down_gui())
donwload_btn.place(x=745, y=25)
# 创建多选框
draw_flag = tk.BooleanVar()
draw_btn = tk.Checkbutton(root, text="是否生成规划图", variable=draw_flag)
draw_btn.place(x=495, y=28)
result_flag = tk.BooleanVar()
result_btn = tk.Checkbutton(root, text="是否保存分析结果", variable=result_flag)
result_btn.place(x=605, y=28)
# 创建文本框
text_box = tk.Text(root, height=30, width=100)
text_box.place(x=5, y=70, relwidth=0.98, relheight=0.85)
# 创建纵向滚动条
scrollbar = tk.Scrollbar(text_box, command=text_box.yview)
scrollbar.pack(side=tk.RIGHT, fill=tk.Y)
text_box.config(yscrollcommand=scrollbar.set)
root.protocol("WM_DELETE_WINDOW", on_closing)
# 未选择文件禁用按钮
if label_content.cget("text") == "No directory selected":
button_set_disabled()
# 启动主循环
root.mainloop()