fkudidi

67 阅读31分钟

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()