import time
import zcanpro
import tkinter as tk
from tkinter import filedialog, messagebox, scrolledtext
import threading
# 全局变量
stopTask = False
id = []
name = []
comment = []
data = []
out_str = "VERSION \"\"\n\n\nNS_ : \n\tNS_DESC_\n\tCM_\n\tBA_DEF_\n\tBA_\n\tVAL_\n\tCAT_DEF_\n\tCAT_\n\tFILTER\n\tBA_DEF_DEF_\n\tEV_DATA_\n\tENVVAR_DATA_\n\tSGTYPE_\n\tSGTYPE_VAL_\n\tBA_DEF_SGTYPE_\n\tBA_SGTYPE_\n\tSIG_TYPE_REF_\n\tVAL_TABLE_\n\tSIG_GROUP_\n\tSIG_VALTYPE_\n\tSIGTYPE_VALTYPE_\n\tBO_TX_BU_\n\tBA_DEF_REL_\n\tBA_REL_\n\tBA_DEF_DEF_REL_\n\tBU_SG_REL_\n\tBU_EV_REL_\n\tBU_BO_REL_\n\tSG_MUL_VAL_\n\nBS_:\n\nBU_:\n\n\n"
def z_notify(type, obj):
zcanpro.write_log("Notify " + str(type) + " " + str(obj))
if type == "stop":
zcanpro.write_log("脚本停止")
global stopTask
stopTask = True
def select_input_file():
file_path = filedialog.askopenfilename(
title="选择输入文件",
filetypes=[("文本文件", "*.txt"), ("所有文件", "*.*")]
)
if file_path:
input_entry.delete(0, tk.END)
input_entry.insert(0, file_path)
return file_path
return None
def select_output_file():
file_path = filedialog.asksaveasfilename(
title="保存输出文件",
filetypes=[("DBC文件", "*.dbc"), ("所有文件", "*.*")],
defaultextension=".dbc"
)
if file_path:
output_entry.delete(0, tk.END)
output_entry.insert(0, file_path)
return file_path
return None
def run_script():
input_file = input_entry.get()
output_file = output_entry.get()
if not input_file or not output_file:
messagebox.showerror("错误", "请选择输入和输出文件路径")
return
# 在新线程中运行脚本
threading.Thread(target=process_files, args=(input_file, output_file)).start()
def process_files(input_path, output_path):
global id, name, comment, data, out_str
# 重置全局变量
id = []
name = []
comment = []
data = []
out_str = "VERSION \"\"\n\n\nNS_ : \n\tNS_DESC_\n\tCM_\n\tBA_DEF_\n\tBA_\n\tVAL_\n\tCAT_DEF_\n\tCAT_\n\tFILTER\n\tBA_DEF_DEF_\n\tEV_DATA_\n\tENVVAR_DATA_\n\tSGTYPE_\n\tSGTYPE_VAL_\n\tBA_DEF_SGTYPE_\n\tBA_SGTYPE_\n\tSIG_TYPE_REF_\n\tVAL_TABLE_\n\tSIG_GROUP_\n\tSIG_VALTYPE_\n\tSIGTYPE_VALTYPE_\n\tBO_TX_BU_\n\tBA_DEF_REL_\n\tBA_REL_\n\tBA_DEF_DEF_REL_\n\tBU_SG_REL_\n\tBU_EV_REL_\n\tBU_BO_REL_\n\tSG_MUL_VAL_\n\nBS_:\n\nBU_:\n\n\n"
zcanpro.write_log("读取数据……")
try:
input = open(input_path, "r", encoding="UTF-8")
lines = input.readlines()
n = l = 0
while(l < len(lines)):
if lines[l].strip() == "":
l += 1
continue
line = lines[l].strip('\n').split('\t')
line.append("") # 防止index溢出
if line[0] == "ID" and line[2] == "名称" and line[4] == "帧格式":
if line[5] == "扩展帧":
line[1] = '9' + line[1][1:]
id.append(str(int(line[1], 16)))
name.append(line[3])
comment.append(line[7])
n += 1
data.append([])
zcanpro.write_log(f"读取ID: 0x{hex(int(id[n-1],10) & 0x1FFFFFFF)[2:].upper()}……")
else:
i = 0
if line[3] == "Intel":
line[3] = "1"
else:
line[3] = "0"
if line[4] == "":
line[4] = "1"
if line[5] == "":
line[5] = "0"
data[n-1].append(line)
l += 1
input.close()
except Exception as e:
zcanpro.write_log(f"{e}")
messagebox.showerror("错误", f"读取文件时出错: {e}")
return
zcanpro.write_log("数据读取完成")
zcanpro.write_log("编写格式……")
try:
for i in range(n):
out_str += "BO_ " + id[i] + " " + name[i] + ": 8 Vector__XXX\n"
for j in range(len(data[i])):
out_str += " SG_ " + data[i][j][0] + " : " + data[i][j][1] + "|" + data[i][j][2] + "@" + data[i][j][3] + "+ (" + data[i][j][4] + "," + data[i][j][5] + ") [0|0] \"" + data[i][j][6] + "\" Vector__XXX\n"
out_str += "\n"
out_str += "\n\n"
for i in range(n):
out_str += "CM_ BO_ " + id[i] + " \"" + comment[i] + "\";\n"
for j in range(len(data[i])):
out_str += "CM_ SG_ "+ id[i] + " " + data[i][j][0] + " \"" + data[i][j][7] + "\";\n"
out_str += "BA_DEF_ SG_ \"GenSigSendType\" ENUM \"Cyclic\",\"OnWrite\",\"OnWriteWithRepetition\",\"OnChange\",\"OnChangeWithRepetition\",\"IfActive\",\"IfActiveWithRepetition\",\"NoSigSendType\";\nBA_DEF_ SG_ \"GenSigInactiveValue\" INT 0 0;\nBA_DEF_ BO_ \"GenMsgCycleTime\" INT 0 0;\nBA_DEF_ BO_ \"GenMsgSendType\" ENUM \"Cyclic\",\"not_used\",\"not_used\",\"not_used\",\"not_used\",\"Cyclic\",\"not_used\",\"IfActive\",\"NoMsgSendType\";\nBA_DEF_ BU_ \"NmStationAddress\" HEX 0 0;\nBA_DEF_ \"DBName\" STRING ;\nBA_DEF_ \"BusType\" STRING ;\nBA_DEF_ BU_ \"NodeLayerModules\" STRING ;\nBA_DEF_ BU_ \"ECU\" STRING ;\nBA_DEF_ BU_ \"CANoeJitterMax\" INT 0 0;\nBA_DEF_ BU_ \"CANoeJitterMin\" INT 0 0;\nBA_DEF_ BU_ \"CANoeDrift\" INT 0 0;\nBA_DEF_ BU_ \"CANoeStartDelay\" INT 0 0;\nBA_DEF_DEF_ \"GenSigSendType\" \"Cyclic\";\nBA_DEF_DEF_ \"GenSigInactiveValue\" 0;\nBA_DEF_DEF_ \"GenMsgCycleTime\" 0;\nBA_DEF_DEF_ \"GenMsgSendType\" \"NoMsgSendType\";\nBA_DEF_DEF_ \"NmStationAddress\" 0;\nBA_DEF_DEF_ \"DBName\" \"\";\nBA_DEF_DEF_ \"BusType\" \"CAN\";\nBA_DEF_DEF_ \"NodeLayerModules\" \"\";\nBA_DEF_DEF_ \"ECU\" \"\";\nBA_DEF_DEF_ \"CANoeJitterMax\" 0;\nBA_DEF_DEF_ \"CANoeJitterMin\" 0;\nBA_DEF_DEF_ \"CANoeDrift\" 0;\nBA_DEF_DEF_ \"CANoeStartDelay\" 0;\nBA_ \"DBName\" \"TEMP\";\n"
for i in range(n):
for j in range(len(data[i])):
value_table = ""
a = len(data[i][j][8:])
for c in reversed(data[i][j][8:]):
a -= 1
if c != "":
value_table += str(a) + " \"" + c + "\" "
if value_table != "":
out_str += "VAL_ "+ id[i] + " " + data[i][j][0] + " " + value_table + ";\n"
except Exception as e:
zcanpro.write_log(f"{e}")
messagebox.showerror("错误", f"处理数据时出错: {e}")
return
zcanpro.write_log("格式编写完成")
zcanpro.write_log("导出文件……")
try:
output = open(output_path, "w", encoding="ANSI")
output.write(out_str)
output.close()
messagebox.showinfo("成功", f"文件已成功导出至: {output_path}")
except Exception as e:
zcanpro.write_log(f"{e}")
messagebox.showerror("错误", f"导出文件时出错: {e}")
return
zcanpro.write_log("文件导出完成")
# 创建GUI界面
def create_gui():
global input_entry, output_entry
root = tk.Tk()
root.title("DBC文件转换工具")
root.geometry("600x400")
# 输入文件选择
input_frame = tk.Frame(root)
input_frame.pack(pady=10, padx=20, fill=tk.X)
tk.Label(input_frame, text="输入文件:").pack(side=tk.LEFT, padx=(0, 10))
input_entry = tk.Entry(input_frame, width=50)
input_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
input_btn = tk.Button(input_frame, text="浏览...", command=select_input_file)
input_btn.pack(side=tk.RIGHT, padx=(10, 0))
# 输出文件选择
output_frame = tk.Frame(root)
output_frame.pack(pady=10, padx=20, fill=tk.X)
tk.Label(output_frame, text="输出文件:").pack(side=tk.LEFT, padx=(0, 10))
output_entry = tk.Entry(output_frame, width=50)
output_entry.pack(side=tk.LEFT, fill=tk.X, expand=True)
output_btn = tk.Button(output_frame, text="浏览...", command=select_output_file)
output_btn.pack(side=tk.RIGHT, padx=(10, 0))
# 日志窗口
log_frame = tk.LabelFrame(root, text="日志输出")
log_frame.pack(pady=10, padx=20, fill=tk.BOTH, expand=True)
log_text = scrolledtext.ScrolledText(log_frame, height=10)
log_text.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
# 重定向日志到GUI窗口
def write_log_gui(message):
log_text.insert(tk.END, message + "\n")
log_text.see(tk.END)
# 替换zcanpro.write_log函数
original_write_log = zcanpro.write_log
zcanpro.write_log = lambda msg: (original_write_log(msg), write_log_gui(msg))
# 运行按钮
run_btn = tk.Button(root, text="运行转换", command=run_script, height=2, width=20)
run_btn.pack(pady=20)
root.mainloop()
# 主入口
if __name__ == "__main__":
create_gui()
上述代码为何删除重定向到日志窗口的内容后运行两次就崩溃?
最新发布