Code: Select all
import tkinter as tk
from tkinter import ttk
import re
from tkinterdnd2 import DND_FILES, TkinterDnD
import os
class FactorioConfigComparer(TkinterDnD.Tk):
def __init__(self):
super().__init__()
self.title("Factorio Config Comparer")
self.geometry("1000x600")
# 创建主框架
self.main_frame = ttk.Frame(self)
self.main_frame.pack(expand=True, fill='both', padx=10, pady=10)
# 创建左右两栏
self.create_panels()
# 创建对比结果区域
self.create_result_area()
# 存储当前加载的配置
self.left_config = None
self.right_config = None
def create_panels(self):
# 创建左右面板容器
panels_frame = ttk.Frame(self.main_frame)
panels_frame.pack(expand=True, fill='both')
# 左面板
left_frame = ttk.LabelFrame(panels_frame, text="Left Config File")
left_frame.pack(side='left', expand=True, fill='both', padx=5)
self.left_text = tk.Text(left_frame, height=10, wrap=tk.WORD)
self.left_text.pack(expand=True, fill='both', padx=5, pady=5)
self.left_text.insert('1.0', "Drop .cfg file here")
# 配置拖放
self.left_text.drop_target_register(DND_FILES)
self.left_text.dnd_bind('<<Drop>>', lambda e: self.on_drop(e, 'left'))
# 右面板
right_frame = ttk.LabelFrame(panels_frame, text="Right Config File")
right_frame.pack(side='left', expand=True, fill='both', padx=5)
self.right_text = tk.Text(right_frame, height=10, wrap=tk.WORD)
self.right_text.pack(expand=True, fill='both', padx=5, pady=5)
self.right_text.insert('1.0', "Drop .cfg file here")
# 配置拖放
self.right_text.drop_target_register(DND_FILES)
self.right_text.dnd_bind('<<Drop>>', lambda e: self.on_drop(e, 'right'))
def create_result_area(self):
# 创建结果显示区域
result_frame = ttk.LabelFrame(self.main_frame, text="Comparison Results")
result_frame.pack(expand=True, fill='both', pady=10)
# 创建两个子区域用于显示缺失的键
results_container = ttk.Frame(result_frame)
results_container.pack(expand=True, fill='both')
# 左侧缺失的键
left_missing_frame = ttk.LabelFrame(results_container, text="Keys missing in Left file")
left_missing_frame.pack(side='left', expand=True, fill='both', padx=5, pady=5)
self.left_missing_text = tk.Text(left_missing_frame, height=10, wrap=tk.WORD)
self.left_missing_text.pack(expand=True, fill='both', padx=5, pady=5)
# 右侧缺失的键
right_missing_frame = ttk.LabelFrame(results_container, text="Keys missing in Right file")
right_missing_frame.pack(side='left', expand=True, fill='both', padx=5, pady=5)
self.right_missing_text = tk.Text(right_missing_frame, height=10, wrap=tk.WORD)
self.right_missing_text.pack(expand=True, fill='both', padx=5, pady=5)
def parse_factorio_cfg(self, file_path):
"""解析 Factorio 配置文件,返回键值对字典"""
config_dict = {}
current_key = None
with open(file_path, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
# 跳过空行和注释
if not line or line.startswith('#') or line.startswith('_'):
continue
# 检查是否是键值对
if '=' in line:
key, value = line.split('=', 1)
key = key.strip()
value = value.strip()
# 去掉值的引号(如果存在)
value = value.strip('"').strip("'")
config_dict[key] = value
return config_dict
def on_drop(self, event, side):
# 获取拖放的文件路径
file_path = event.data
# 移除可能的大括号和引号
file_path = file_path.strip('{}').strip('"')
# 检查文件是否存在且是.cfg文件
if not os.path.exists(file_path) or not file_path.lower().endswith('.cfg'):
self.show_error("Please drop a valid .cfg file")
return
# 读取配置文件
try:
config_dict = self.parse_factorio_cfg(file_path)
# 更新相应的文本框和存储的配置
if side == 'left':
self.left_text.delete('1.0', tk.END)
self.left_text.insert('1.0', f"Loaded: {os.path.basename(file_path)}\n")
self.left_text.insert(tk.END, f"Found {len(config_dict)} keys")
self.left_config = config_dict
else:
self.right_text.delete('1.0', tk.END)
self.right_text.insert('1.0', f"Loaded: {os.path.basename(file_path)}\n")
self.right_text.insert(tk.END, f"Found {len(config_dict)} keys")
self.right_config = config_dict
# 如果两个配置文件都已加载,则进行比较
if self.left_config and self.right_config:
self.compare_configs()
except Exception as e:
self.show_error(f"Error reading config file: {str(e)}")
def compare_configs(self):
# 清空结果区域
self.left_missing_text.delete('1.0', tk.END)
self.right_missing_text.delete('1.0', tk.END)
# 获取所有键
left_keys = set(self.left_config.keys())
right_keys = set(self.right_config.keys())
# 找出缺失的键
missing_in_left = right_keys - left_keys
missing_in_right = left_keys - right_keys
# 显示结果
if missing_in_left:
for key in sorted(missing_in_left):
self.left_missing_text.insert(tk.END, f"{key}={self.right_config[key]}\n")
else:
self.left_missing_text.insert('1.0', "No missing keys")
if missing_in_right:
for key in sorted(missing_in_right):
self.right_missing_text.insert(tk.END, f"{key}={self.left_config[key]}\n")
else:
self.right_missing_text.insert('1.0', "No missing keys")
def show_error(self, message):
"""显示错误消息"""
import tkinter.messagebox as messagebox
messagebox.showerror("Error", message)
if __name__ == "__main__":
app = FactorioConfigComparer()
app.mainloop()