first
This commit is contained in:
commit
fa00192c6d
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
419
script_manager.py
Normal file
419
script_manager.py
Normal file
@ -0,0 +1,419 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox, filedialog
|
||||
import sqlite3
|
||||
import os
|
||||
import datetime
|
||||
import json
|
||||
import importlib.util
|
||||
from typing import List, Dict
|
||||
import pyperclip
|
||||
|
||||
|
||||
class ScriptManager:
|
||||
def __init__(self, db_path="scripts.db", scripts_dir="scripts"):
|
||||
self.db_path = db_path
|
||||
self.scripts_dir = scripts_dir
|
||||
self._init_db()
|
||||
self._init_scripts_dir()
|
||||
self.tag_library = {
|
||||
"文本": ["string", "text", "format", "generate"],
|
||||
"转换": ["convert", "transform", "format"],
|
||||
"处理": ["process", "handle", "manipulate"],
|
||||
"生成": ["create", "generate", "make"],
|
||||
"解析": ["parse", "extract", "analyze"]
|
||||
}
|
||||
|
||||
def _init_db(self):
|
||||
with sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
CREATE TABLE IF NOT EXISTS scripts (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT NOT NULL,
|
||||
path TEXT NOT NULL,
|
||||
ui_path TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL,
|
||||
tags TEXT,
|
||||
abbreviation TEXT,
|
||||
usage_count INTEGER DEFAULT 0
|
||||
)
|
||||
""")
|
||||
conn.commit()
|
||||
|
||||
def _init_scripts_dir(self):
|
||||
os.makedirs(self.scripts_dir, exist_ok=True)
|
||||
|
||||
def _suggest_tags(self, script_name: str) -> List[str]:
|
||||
name = script_name.lower()
|
||||
suggested_tags = []
|
||||
for category, keywords in self.tag_library.items():
|
||||
if any(keyword in name for keyword in keywords):
|
||||
suggested_tags.append(category)
|
||||
return suggested_tags
|
||||
|
||||
def add_script(self, script_name: str, script_content: str = None, script_path: str = None,
|
||||
ui_content: str = None) -> Dict:
|
||||
if not script_path:
|
||||
script_name_clean = script_name.replace(" ", "_").replace("/", "_").replace("\\", "_")
|
||||
script_path = os.path.join(self.scripts_dir, f"{script_name_clean}.py")
|
||||
|
||||
ui_path = os.path.join(self.scripts_dir, f"{script_name_clean}.ui.py")
|
||||
|
||||
if not script_content:
|
||||
script_content = '''def process(input_strings: list) -> list:
|
||||
"""处理输入字符串并返回结果"""
|
||||
return [s.upper() for s in input_strings]
|
||||
'''
|
||||
|
||||
if not ui_content:
|
||||
ui_content = '''import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import pyperclip
|
||||
|
||||
def create_ui(parent, run_callback):
|
||||
"""创建前端界面"""
|
||||
frame = ttk.Frame(parent)
|
||||
frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
frame.columnconfigure(1, weight=1)
|
||||
|
||||
ttk.Label(frame, text="输入字符串 1:").grid(row=0, column=0, sticky=tk.W, pady=2)
|
||||
input_entry = ttk.Entry(frame)
|
||||
input_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), pady=2)
|
||||
|
||||
ttk.Label(frame, text="输出结果 1:").grid(row=1, column=0, sticky=tk.W, pady=2)
|
||||
output_entry = ttk.Entry(frame, state="readonly")
|
||||
output_entry.grid(row=1, column=1, sticky=(tk.W, tk.E), pady=2)
|
||||
|
||||
def copy_output(event):
|
||||
output = output_entry.get()
|
||||
if output:
|
||||
pyperclip.copy(output)
|
||||
tk.messagebox.showinfo("提示", "输出已复制到剪贴板")
|
||||
|
||||
output_entry.bind("<Button-1>", copy_output)
|
||||
|
||||
def run():
|
||||
input_text = input_entry.get().strip()
|
||||
if not input_text:
|
||||
tk.messagebox.showerror("错误", "请输入字符串")
|
||||
return
|
||||
result = run_callback([input_text])
|
||||
output_entry.configure(state="normal")
|
||||
output_entry.delete(0, tk.END)
|
||||
output_entry.insert(0, result[0] if result else "")
|
||||
output_entry.configure(state="readonly")
|
||||
|
||||
ttk.Button(frame, text="运行脚本", command=run).grid(row=2, column=0, columnspan=2, pady=5)
|
||||
|
||||
return frame
|
||||
'''
|
||||
|
||||
with open(script_path, 'w', encoding='utf-8') as f:
|
||||
f.write(script_content)
|
||||
|
||||
with open(ui_path, 'w', encoding='utf-8') as f:
|
||||
f.write(ui_content)
|
||||
|
||||
abbr = ''.join(word[0].upper() for word in script_name.split('_') if word)
|
||||
suggested_tags = self._suggest_tags(script_name)
|
||||
|
||||
with sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("""
|
||||
INSERT INTO scripts (name, path, ui_path, created_at, tags, abbreviation, usage_count)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?)
|
||||
""", (
|
||||
script_name,
|
||||
script_path,
|
||||
ui_path,
|
||||
datetime.datetime.now().isoformat(),
|
||||
json.dumps(suggested_tags),
|
||||
abbr,
|
||||
0
|
||||
))
|
||||
conn.commit()
|
||||
|
||||
return {
|
||||
"id": cursor.lastrowid,
|
||||
"name": script_name,
|
||||
"path": script_path,
|
||||
"ui_path": ui_path,
|
||||
"suggested_tags": suggested_tags,
|
||||
"abbreviation": abbr
|
||||
}
|
||||
|
||||
def list_scripts(self, tag: str = None, name: str = None) -> List[Dict]:
|
||||
with sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
query = "SELECT * FROM scripts"
|
||||
params = []
|
||||
conditions = []
|
||||
|
||||
if tag:
|
||||
conditions.append("tags LIKE ?")
|
||||
params.append(f'%{tag}%')
|
||||
if name:
|
||||
conditions.append("name LIKE ?")
|
||||
params.append(f'%{name}%')
|
||||
|
||||
if conditions:
|
||||
query += " WHERE " + " AND ".join(conditions)
|
||||
|
||||
cursor.execute(query, params)
|
||||
scripts = []
|
||||
for row in cursor.fetchall():
|
||||
try:
|
||||
tags = json.loads(row[5]) if row[5] and row[5].strip() else []
|
||||
except json.JSONDecodeError:
|
||||
tags = [] # Fallback to empty list if JSON is invalid
|
||||
scripts.append({
|
||||
"id": row[0],
|
||||
"name": row[1],
|
||||
"path": row[2],
|
||||
"created_at": row[3],
|
||||
"tags": tags,
|
||||
"abbreviation": row[5],
|
||||
"usage_count": row[6],
|
||||
"ui_path":row[7]
|
||||
})
|
||||
return scripts
|
||||
|
||||
def run_script(self, script_id: int, input_strings: List[str]) -> List[str]:
|
||||
with sqlite3.connect(self.db_path) as conn:
|
||||
cursor = conn.cursor()
|
||||
cursor.execute("SELECT path FROM scripts WHERE id = ?", (script_id,))
|
||||
result = cursor.fetchone()
|
||||
if not result:
|
||||
raise ValueError("脚本未找到")
|
||||
|
||||
script_path = result[0]
|
||||
cursor.execute("UPDATE scripts SET usage_count = usage_count + 1 WHERE id = ?", (script_id,))
|
||||
conn.commit()
|
||||
|
||||
spec = importlib.util.spec_from_file_location("script_module", script_path)
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module.process(input_strings)
|
||||
|
||||
def load_ui_module(self, ui_path: str):
|
||||
"""加载前端界面模块"""
|
||||
if not ui_path or not os.path.isfile(ui_path):
|
||||
raise ValueError(f"前端界面文件不存在或路径无效:{ui_path}")
|
||||
try:
|
||||
spec = importlib.util.spec_from_file_location("ui_module", ui_path)
|
||||
if spec is None:
|
||||
raise ValueError(f"无法加载前端界面模块:{ui_path} (模块规格无效)")
|
||||
module = importlib.util.module_from_spec(spec)
|
||||
spec.loader.exec_module(module)
|
||||
return module
|
||||
except Exception as e:
|
||||
raise ValueError(f"加载前端界面失败:{str(e)}")
|
||||
|
||||
|
||||
class ScriptManagerGUI:
|
||||
def __init__(self, root):
|
||||
self.root = root
|
||||
self.root.title("脚本管理器")
|
||||
self.manager = ScriptManager()
|
||||
self.selected_script_id = None
|
||||
self.current_ui_frame = None
|
||||
self.create_widgets()
|
||||
self.root.columnconfigure(0, weight=1)
|
||||
self.root.rowconfigure(0, weight=1)
|
||||
|
||||
def create_widgets(self):
|
||||
# 使用 Notebook 创建选项卡
|
||||
self.notebook = ttk.Notebook(self.root)
|
||||
self.notebook.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=10, pady=5)
|
||||
self.notebook.columnconfigure(0, weight=1)
|
||||
self.notebook.rowconfigure(0, weight=1)
|
||||
|
||||
# 添加脚本选项卡
|
||||
add_frame = ttk.Frame(self.notebook, padding="10")
|
||||
self.notebook.add(add_frame, text="添加脚本")
|
||||
add_frame.columnconfigure(1, weight=1)
|
||||
add_frame.rowconfigure(3, weight=1)
|
||||
|
||||
# 脚本名称
|
||||
ttk.Label(add_frame, text="脚本名称:").grid(row=0, column=0, sticky=tk.W, pady=5)
|
||||
self.script_name_var = tk.StringVar()
|
||||
ttk.Entry(add_frame, textvariable=self.script_name_var).grid(row=0, column=1, sticky=(tk.W, tk.E), pady=5)
|
||||
|
||||
# 脚本路径
|
||||
ttk.Label(add_frame, text="脚本路径(可选):").grid(row=1, column=0, sticky=tk.W, pady=5)
|
||||
self.script_path_var = tk.StringVar()
|
||||
ttk.Entry(add_frame, textvariable=self.script_path_var).grid(row=1, column=1, sticky=(tk.W, tk.E), pady=5)
|
||||
ttk.Button(add_frame, text="选择文件", command=self.browse_file).grid(row=1, column=2, padx=5)
|
||||
|
||||
# 标签
|
||||
ttk.Label(add_frame, text="标签(逗号分隔,可选):").grid(row=2, column=0, sticky=tk.W, pady=5)
|
||||
self.tags_var = tk.StringVar()
|
||||
ttk.Entry(add_frame, textvariable=self.tags_var).grid(row=2, column=1, sticky=(tk.W, tk.E), pady=5)
|
||||
|
||||
# 脚本内容
|
||||
ttk.Label(add_frame, text="脚本内容(可选):").grid(row=3, column=0, sticky=tk.W, pady=5)
|
||||
self.script_content_text = tk.Text(add_frame, height=5)
|
||||
self.script_content_text.grid(row=3, column=1, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
|
||||
|
||||
# 前端界面内容
|
||||
ttk.Label(add_frame, text="前端界面内容(可选):").grid(row=4, column=0, sticky=tk.W, pady=5)
|
||||
self.ui_content_text = tk.Text(add_frame, height=5)
|
||||
self.ui_content_text.grid(row=4, column=1, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=5)
|
||||
|
||||
ttk.Button(add_frame, text="添加脚本", command=self.add_script).grid(row=5, column=0, columnspan=3, pady=5)
|
||||
|
||||
# 索引运行脚本选项卡
|
||||
run_frame = ttk.Frame(self.notebook, padding="10")
|
||||
self.notebook.add(run_frame, text="索引运行脚本")
|
||||
run_frame.columnconfigure(0, weight=1)
|
||||
run_frame.columnconfigure(2, weight=1)
|
||||
run_frame.rowconfigure(0, weight=1)
|
||||
|
||||
# 左侧:搜索和脚本列表
|
||||
left_frame = ttk.Frame(run_frame)
|
||||
left_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(0, 5))
|
||||
left_frame.columnconfigure(0, weight=1)
|
||||
left_frame.rowconfigure(1, weight=1)
|
||||
|
||||
ttk.Label(left_frame, text="搜索(名称或标签):").grid(row=0, column=0, sticky=tk.W, pady=5)
|
||||
self.search_var = tk.StringVar()
|
||||
ttk.Entry(left_frame, textvariable=self.search_var).grid(row=0, column=1, sticky=(tk.W, tk.E), pady=5)
|
||||
ttk.Button(left_frame, text="搜索", command=self.search_scripts).grid(row=0, column=2, padx=5)
|
||||
|
||||
self.tree = ttk.Treeview(left_frame, columns=("ID", "名称", "标签", "缩写", "使用次数", "创建时间"),
|
||||
show="headings")
|
||||
# Set column headings
|
||||
self.tree.heading("ID", text="ID")
|
||||
self.tree.heading("名称", text="名称")
|
||||
self.tree.heading("标签", text="标签")
|
||||
self.tree.heading("缩写", text="缩写")
|
||||
self.tree.heading("使用次数", text="使用次数")
|
||||
self.tree.heading("创建时间", text="创建时间")
|
||||
|
||||
# Set column widths (in pixels)
|
||||
self.tree.column("ID", width=25, minwidth=25, stretch=False) # Narrow for ID
|
||||
self.tree.column("名称", width=150, minwidth=100, stretch=True) # Wider for name
|
||||
self.tree.column("标签", width=100, minwidth=80, stretch=True) # Medium for tags
|
||||
self.tree.column("缩写", width=60, minwidth=50, stretch=False) # Narrow for abbreviation
|
||||
self.tree.column("使用次数", width=80, minwidth=60, stretch=False) # Narrow for usage count
|
||||
self.tree.column("创建时间", width=120, minwidth=100, stretch=True) # Medium for date
|
||||
|
||||
# Place the Treeview in the grid
|
||||
self.tree.grid(row=1, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
self.tree.bind("<<TreeviewSelect>>", self.on_script_select)
|
||||
# 分割线
|
||||
ttk.Separator(run_frame, orient=tk.VERTICAL).grid(row=0, column=1, sticky=(tk.N, tk.S), padx=5)
|
||||
|
||||
# 右侧:动态前端界面
|
||||
self.io_frame = ttk.Frame(run_frame)
|
||||
self.io_frame.grid(row=0, column=2, sticky=(tk.W, tk.E, tk.N, tk.S), padx=(5, 0))
|
||||
self.io_frame.columnconfigure(0, weight=1)
|
||||
self.io_frame.rowconfigure(0, weight=1)
|
||||
|
||||
# 加载脚本列表
|
||||
self.refresh_script_list()
|
||||
|
||||
def browse_file(self):
|
||||
file_path = filedialog.askopenfilename(filetypes=[("Python files", "*.py")])
|
||||
if file_path:
|
||||
self.script_path_var.set(file_path)
|
||||
|
||||
def refresh_script_list(self, search_term: str = None):
|
||||
for item in self.tree.get_children():
|
||||
self.tree.delete(item)
|
||||
scripts = self.manager.list_scripts(tag=search_term, name=search_term)
|
||||
for script in scripts:
|
||||
self.tree.insert("", tk.END, values=(
|
||||
script["id"],
|
||||
script["name"],
|
||||
", ".join(script["tags"]),
|
||||
script["abbreviation"],
|
||||
script["usage_count"],
|
||||
script["created_at"]
|
||||
))
|
||||
|
||||
def add_script(self):
|
||||
script_name = self.script_name_var.get().strip()
|
||||
script_path = self.script_path_var.get().strip()
|
||||
script_content = self.script_content_text.get("1.0", tk.END).strip()
|
||||
ui_content = self.ui_content_text.get("1.0", tk.END).strip()
|
||||
tags = [t.strip() for t in self.tags_var.get().split(",") if t.strip()]
|
||||
|
||||
if not script_name and not script_path:
|
||||
messagebox.showerror("错误", "脚本名称和脚本路径不能同时为空")
|
||||
return
|
||||
if not script_path and not script_content:
|
||||
messagebox.showerror("错误", "脚本路径和脚本内容不能同时为空")
|
||||
return
|
||||
if not script_name and script_path:
|
||||
script_name = os.path.splitext(os.path.basename(script_path))[0]
|
||||
|
||||
try:
|
||||
result = self.manager.add_script(script_name, script_content or None, script_path or None,
|
||||
ui_content or None)
|
||||
if tags:
|
||||
self.manager.update_tags(result["id"], tags)
|
||||
messagebox.showinfo("成功", f"脚本 '{script_name}' 已添加!\n建议标签:{', '.join(result['suggested_tags'])}")
|
||||
self.script_name_var.set("")
|
||||
self.script_path_var.set("")
|
||||
self.script_content_text.delete("1.0", tk.END)
|
||||
self.ui_content_text.delete("1.0", tk.END)
|
||||
self.tags_var.set(", ".join(result["suggested_tags"]))
|
||||
self.refresh_script_list()
|
||||
except Exception as e:
|
||||
messagebox.showerror("错误", f"添加脚本失败:{str(e)}")
|
||||
|
||||
def on_script_select(self, event):
|
||||
selection = self.tree.selection()
|
||||
if selection:
|
||||
item = self.tree.item(selection[0])
|
||||
self.selected_script_id = int(item["values"][0])
|
||||
script = next(s for s in self.manager.list_scripts() if s["id"] == self.selected_script_id)
|
||||
self.refresh_io_frame(script["ui_path"], script["path"])
|
||||
|
||||
def refresh_io_frame(self, ui_path: str = None, script_path: str = None):
|
||||
# 清空现有界面
|
||||
if self.current_ui_frame:
|
||||
self.current_ui_frame.destroy()
|
||||
|
||||
if not ui_path or not script_path:
|
||||
self.current_ui_frame = ttk.Label(
|
||||
self.io_frame,
|
||||
text="请选择一个脚本",
|
||||
wraplength=int(self.io_frame.winfo_width() * 0.9) or 300
|
||||
)
|
||||
self.current_ui_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
return
|
||||
|
||||
try:
|
||||
# 加载前端界面模块
|
||||
ui_module = self.manager.load_ui_module(ui_path)
|
||||
|
||||
# 创建运行回调
|
||||
def run_callback(input_strings):
|
||||
return self.manager.run_script(self.selected_script_id, input_strings)
|
||||
|
||||
# 调用前端界面的 create_ui 函数
|
||||
self.current_ui_frame = ui_module.create_ui(self.io_frame, run_callback)
|
||||
self.current_ui_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
except Exception as e:
|
||||
frame_width = self.io_frame.winfo_width() or 300
|
||||
self.current_ui_frame = ttk.Label(
|
||||
self.io_frame,
|
||||
text=f"加载前端界面失败:{str(e)}",
|
||||
wraplength=int(frame_width * 0.9),
|
||||
padding=(5, 5),
|
||||
foreground="red"
|
||||
)
|
||||
self.current_ui_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
|
||||
def search_scripts(self):
|
||||
search_term = self.search_var.get().strip()
|
||||
self.refresh_script_list(search_term)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
root = tk.Tk()
|
||||
root.geometry("800x600")
|
||||
app = ScriptManagerGUI(root)
|
||||
root.mainloop()
|
BIN
scripts.db
Normal file
BIN
scripts.db
Normal file
Binary file not shown.
34
scripts/json数组元素字段拼接.py
Normal file
34
scripts/json数组元素字段拼接.py
Normal file
@ -0,0 +1,34 @@
|
||||
import json
|
||||
import re
|
||||
|
||||
def process(input_strings: list) -> list:
|
||||
"""解析 JSON 数组,提取用户指定的字段并按模板拼接"""
|
||||
json_str, template = input_strings[0], input_strings[1]
|
||||
try:
|
||||
# 解析 JSON
|
||||
data = json.loads(json_str)
|
||||
if not isinstance(data, dict) or "data" not in data or not isinstance(data["data"], list):
|
||||
return ["错误:JSON 格式无效,缺少 'data' 数组或不是数组"]
|
||||
|
||||
# 提取模板中的字段名(形如 $field$)
|
||||
fields = re.findall(r'\$([^\$]+)\$', template)
|
||||
if not fields:
|
||||
return ["错误:模板中未找到有效字段(格式如 $field$)"]
|
||||
|
||||
# 拼接结果
|
||||
result = []
|
||||
for item in data["data"]:
|
||||
# 替换模板中的字段
|
||||
formatted = template
|
||||
for field in fields:
|
||||
# 获取字段值,缺失时用 "N/A"
|
||||
value = str(item.get(field, "N/A"))
|
||||
formatted = formatted.replace(f"${field}$", value)
|
||||
result.append(formatted)
|
||||
|
||||
# 返回拼接字符串
|
||||
return [",".join(result)] if result else ["无有效数据"]
|
||||
except json.JSONDecodeError:
|
||||
return ["错误:无效的 JSON 字符串"]
|
||||
except Exception as e:
|
||||
return [f"错误:{str(e)}"]
|
111
scripts/json数组元素字段拼接.ui.py
Normal file
111
scripts/json数组元素字段拼接.ui.py
Normal file
@ -0,0 +1,111 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import pyperclip
|
||||
from tkinter import messagebox
|
||||
import json
|
||||
|
||||
def create_ui(parent, run_callback):
|
||||
"""创建前端界面:JSON 输入、字段选择、模板输入、输出显示"""
|
||||
frame = ttk.Frame(parent)
|
||||
frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
frame.columnconfigure(1, weight=1)
|
||||
frame.rowconfigure(1, weight=1)
|
||||
frame.rowconfigure(4, weight=1)
|
||||
|
||||
# 描述
|
||||
ttk.Label(frame, text="解析 JSON 数组,按模板拼接指定字段(如 $field$:OJ:$field2$)").grid(
|
||||
row=0, column=0, columnspan=3, sticky=tk.W, pady=5
|
||||
)
|
||||
|
||||
# JSON 输入
|
||||
ttk.Label(frame, text="输入 JSON:").grid(row=1, column=0, sticky=tk.NW, pady=2)
|
||||
input_text = tk.Text(frame, height=5, width=50)
|
||||
input_text.grid(row=1, column=1, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=2)
|
||||
input_scroll = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=input_text.yview)
|
||||
input_scroll.grid(row=1, column=3, sticky=(tk.N, tk.S))
|
||||
input_text["yscrollcommand"] = input_scroll.set
|
||||
|
||||
# 字段选择
|
||||
ttk.Label(frame, text="可用字段:").grid(row=2, column=0, sticky=tk.NW, pady=2)
|
||||
field_listbox = tk.Listbox(frame, height=5, selectmode=tk.SINGLE)
|
||||
field_listbox.grid(row=2, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), pady=2)
|
||||
field_scroll = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=field_listbox.yview)
|
||||
field_scroll.grid(row=2, column=2, sticky=(tk.N, tk.S))
|
||||
field_listbox["yscrollcommand"] = field_scroll.set
|
||||
|
||||
def detect_fields():
|
||||
"""检测 JSON 中的字段"""
|
||||
field_listbox.delete(0, tk.END)
|
||||
json_str = input_text.get("1.0", tk.END).strip()
|
||||
try:
|
||||
data = json.loads(json_str)
|
||||
if isinstance(data, dict) and "data" in data and isinstance(data["data"], list) and data["data"]:
|
||||
fields = set(data["data"][0].keys())
|
||||
for field in sorted(fields):
|
||||
field_listbox.insert(tk.END, field)
|
||||
else:
|
||||
messagebox.showerror("错误", "JSON 格式无效或缺少 'data' 数组")
|
||||
except json.JSONDecodeError:
|
||||
messagebox.showerror("错误", "无效的 JSON 字符串")
|
||||
except Exception as e:
|
||||
messagebox.showerror("错误", f"检测失败:{str(e)}")
|
||||
|
||||
def add_to_template():
|
||||
"""将选中的字段添加到模板"""
|
||||
selected = field_listbox.curselection()
|
||||
if not selected:
|
||||
messagebox.showwarning("警告", "请选择一个字段")
|
||||
return
|
||||
field = field_listbox.get(selected[0])
|
||||
template_entry.insert(tk.END, f"${field}$")
|
||||
|
||||
ttk.Button(frame, text="检测字段", command=detect_fields).grid(row=3, column=1, sticky=tk.W, pady=2)
|
||||
ttk.Button(frame, text="添加到模板", command=add_to_template).grid(row=3, column=1, sticky=tk.E, pady=2)
|
||||
|
||||
# 模板输入
|
||||
ttk.Label(frame, text="拼接模板:").grid(row=4, column=0, sticky=tk.NW, pady=2)
|
||||
template_entry = ttk.Entry(frame)
|
||||
template_entry.grid(row=4, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=2)
|
||||
|
||||
# 输出
|
||||
ttk.Label(frame, text="输出结果:").grid(row=5, column=0, sticky=tk.NW, pady=2)
|
||||
output_text = tk.Text(frame, height=5, width=50, state="disabled")
|
||||
output_text.grid(row=5, column=1, columnspan=2, sticky=(tk.W, tk.E, tk.N, tk.S), pady=2)
|
||||
output_scroll = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=output_text.yview)
|
||||
output_scroll.grid(row=5, column=3, sticky=(tk.N, tk.S))
|
||||
output_text["yscrollcommand"] = output_scroll.set
|
||||
|
||||
def copy_output(event):
|
||||
output = output_text.get("1.0", tk.END).strip()
|
||||
if output:
|
||||
pyperclip.copy(output)
|
||||
messagebox.showinfo("提示", "输出已复制到剪贴板")
|
||||
|
||||
output_text.bind("<Button-1>", copy_output)
|
||||
|
||||
# 运行按钮
|
||||
def run():
|
||||
json_str = input_text.get("1.0", tk.END).strip()
|
||||
template = template_entry.get().strip()
|
||||
if not json_str or not template:
|
||||
messagebox.showerror("错误", "请输入 JSON 和模板")
|
||||
return
|
||||
result = run_callback([json_str, template])
|
||||
output_text.configure(state="normal")
|
||||
output_text.delete("1.0", tk.END)
|
||||
output_text.insert("1.0", result[0] if result else "无结果")
|
||||
output_text.configure(state="disabled")
|
||||
|
||||
# 清空按钮
|
||||
def clear():
|
||||
input_text.delete("1.0", tk.END)
|
||||
template_entry.delete(0, tk.END)
|
||||
field_listbox.delete(0, tk.END)
|
||||
output_text.configure(state="normal")
|
||||
output_text.delete("1.0", tk.END)
|
||||
output_text.configure(state="disabled")
|
||||
|
||||
ttk.Button(frame, text="运行脚本", command=run).grid(row=6, column=0, pady=5)
|
||||
ttk.Button(frame, text="清空", command=clear).grid(row=6, column=1, sticky=tk.W, pady=5)
|
||||
|
||||
return frame
|
3
scripts/reverse_string.py
Normal file
3
scripts/reverse_string.py
Normal file
@ -0,0 +1,3 @@
|
||||
def process(input_strings: list) -> list:
|
||||
"""反转输入字符串"""
|
||||
return [input_strings[0][::-1]]
|
41
scripts/reverse_string.ui.py
Normal file
41
scripts/reverse_string.ui.py
Normal file
@ -0,0 +1,41 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import pyperclip
|
||||
|
||||
|
||||
def create_ui(parent, run_callback):
|
||||
"""创建前端界面"""
|
||||
frame = ttk.Frame(parent)
|
||||
frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
frame.columnconfigure(1, weight=1)
|
||||
|
||||
ttk.Label(frame, text="输入字符串 1:").grid(row=0, column=0, sticky=tk.W, pady=2)
|
||||
input_entry = ttk.Entry(frame)
|
||||
input_entry.grid(row=0, column=1, sticky=(tk.W, tk.E), pady=2)
|
||||
|
||||
ttk.Label(frame, text="输出结果 1:").grid(row=1, column=0, sticky=tk.W, pady=2)
|
||||
output_entry = ttk.Entry(frame, state="readonly")
|
||||
output_entry.grid(row=1, column=1, sticky=(tk.W, tk.E), pady=2)
|
||||
|
||||
def copy_output(event):
|
||||
output = output_entry.get()
|
||||
if output:
|
||||
pyperclip.copy(output)
|
||||
tk.messagebox.showinfo("提示", "输出已复制到剪贴板")
|
||||
|
||||
output_entry.bind("<Button-1>", copy_output)
|
||||
|
||||
def run():
|
||||
input_text = input_entry.get().strip()
|
||||
if not input_text:
|
||||
tk.messagebox.showerror("错误", "请输入字符串")
|
||||
return
|
||||
result = run_callback([input_text])
|
||||
output_entry.configure(state="normal")
|
||||
output_entry.delete(0, tk.END)
|
||||
output_entry.insert(0, result[0] if result else "")
|
||||
output_entry.configure(state="readonly")
|
||||
|
||||
ttk.Button(frame, text="运行脚本", command=run).grid(row=2, column=0, columnspan=2, pady=5)
|
||||
|
||||
return frame
|
45
scripts/多个字符串拼接为一个.py
Normal file
45
scripts/多个字符串拼接为一个.py
Normal file
@ -0,0 +1,45 @@
|
||||
def process(input_strings: list) -> list:
|
||||
"""将多个字符串按位置拼接为 str1:str2:str3,...,支持自定义输入和输出分隔符"""
|
||||
try:
|
||||
if len(input_strings) < 4:
|
||||
return ["错误:请至少输入两个字符串、一个输入分隔符和一个输出分隔符"]
|
||||
|
||||
# 提取分隔符
|
||||
output_separator = input_strings[-1].strip() # 输出分隔符
|
||||
input_separator = input_strings[-2].strip() # 输入分隔符
|
||||
if not input_separator or not output_separator:
|
||||
return ["错误:输入和输出分隔符不能为空"]
|
||||
# 支持换行符
|
||||
if input_separator == "\\n":
|
||||
input_separator = "\n"
|
||||
if output_separator == "\\n":
|
||||
output_separator = "\n"
|
||||
|
||||
# 输入字符串(除去最后两个分隔符)
|
||||
input_strings = input_strings[:-2]
|
||||
if len(input_strings) < 2:
|
||||
return ["错误:请至少输入两个字符串"]
|
||||
|
||||
# 分割每个字符串为列表
|
||||
element_lists = []
|
||||
for s in input_strings:
|
||||
if not s.strip():
|
||||
return ["错误:输入字符串不能为空"]
|
||||
elements = [e.strip() for e in s.split(input_separator) if e.strip()]
|
||||
element_lists.append(elements)
|
||||
|
||||
# 检查元素数量是否一致
|
||||
length = len(element_lists[0])
|
||||
if not all(len(elements) == length for elements in element_lists):
|
||||
return ["错误:所有字符串的元素数量必须相同"]
|
||||
|
||||
# 按位置拼接
|
||||
result = []
|
||||
for i in range(length):
|
||||
concatenated = ":".join(elements[i] for elements in element_lists)
|
||||
result.append(concatenated)
|
||||
|
||||
# 使用指定的输出分隔符连接结果
|
||||
return [output_separator.join(result)]
|
||||
except Exception as e:
|
||||
return [f"错误:{str(e)}"]
|
144
scripts/多个字符串拼接为一个.ui.py
Normal file
144
scripts/多个字符串拼接为一个.ui.py
Normal file
@ -0,0 +1,144 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import pyperclip
|
||||
from tkinter import messagebox
|
||||
|
||||
def create_ui(parent, run_callback):
|
||||
"""创建前端界面:动态多行输入框、输入/输出分隔符、输出框、运行、清空和添加按钮"""
|
||||
frame = ttk.Frame(parent)
|
||||
frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
frame.columnconfigure(0, weight=1)
|
||||
frame.rowconfigure(1, weight=1)
|
||||
|
||||
# 描述
|
||||
ttk.Label(frame, text="将多个字符串按位置拼接为 str1:str2:str3,...,支持自定义输入分隔符和输出分隔符(如 \\n 表示换行)").grid(
|
||||
row=0, column=0, columnspan=3, sticky=tk.W, pady=5
|
||||
)
|
||||
|
||||
# 可滚动区域,用于输入框
|
||||
canvas = tk.Canvas(frame)
|
||||
canvas.grid(row=1, column=0, columnspan=3, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
scrollbar = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=canvas.yview)
|
||||
scrollbar.grid(row=1, column=3, sticky=(tk.N, tk.S))
|
||||
canvas.configure(yscrollcommand=scrollbar.set)
|
||||
|
||||
# 内部框架,包含输入框
|
||||
inner_frame = ttk.Frame(canvas)
|
||||
canvas_frame_id = canvas.create_window((0, 0), window=inner_frame, anchor=tk.NW)
|
||||
|
||||
def update_scrollregion(event=None):
|
||||
"""更新滚动区域"""
|
||||
canvas.configure(scrollregion=canvas.bbox("all"))
|
||||
canvas.itemconfig(canvas_frame_id, width=canvas.winfo_width())
|
||||
|
||||
inner_frame.bind("<Configure>", update_scrollregion)
|
||||
|
||||
# 存储动态控件
|
||||
input_texts = []
|
||||
input_labels = []
|
||||
input_separator_entry = None
|
||||
output_separator_entry = None
|
||||
output_label = ttk.Label(frame, text="输出结果:")
|
||||
output_text = tk.Text(frame, height=4, width=50, state="disabled")
|
||||
output_scroll = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=output_text.yview)
|
||||
add_button = None
|
||||
run_button = None
|
||||
clear_button = None
|
||||
|
||||
def add_input_field():
|
||||
"""添加新的多行输入框,无数量限制"""
|
||||
nonlocal output_label, output_text, output_scroll, add_button, run_button, clear_button, input_separator_entry, output_separator_entry
|
||||
row = len(input_texts)
|
||||
label = ttk.Label(inner_frame, text=f"字符串{row + 1}:")
|
||||
label.grid(row=row, column=0, sticky=tk.NW, pady=2)
|
||||
text = tk.Text(inner_frame, height=3, width=50)
|
||||
text.grid(row=row, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=2)
|
||||
input_labels.append(label)
|
||||
input_texts.append(text)
|
||||
inner_frame.columnconfigure(1, weight=1)
|
||||
# 更新滚动区域
|
||||
update_scrollregion()
|
||||
|
||||
# 初始化两个输入框
|
||||
for _ in range(2):
|
||||
add_input_field()
|
||||
|
||||
# 输入分隔符
|
||||
input_separator_label = ttk.Label(frame, text="输入分隔符(\\n 表示换行):")
|
||||
input_separator_label.grid(row=2, column=0, sticky=tk.W, pady=2)
|
||||
input_separator_entry = ttk.Entry(frame, width=5)
|
||||
input_separator_entry.insert(0, ",") # 默认逗号
|
||||
input_separator_entry.grid(row=2, column=1, sticky=tk.W, pady=2)
|
||||
|
||||
# 输出分隔符
|
||||
output_separator_label = ttk.Label(frame, text="输出分隔符(\\n 表示换行):")
|
||||
output_separator_label.grid(row=3, column=0, sticky=tk.W, pady=2)
|
||||
output_separator_entry = ttk.Entry(frame, width=5)
|
||||
output_separator_entry.insert(0, ",") # 默认逗号
|
||||
output_separator_entry.grid(row=3, column=1, sticky=tk.W, pady=2)
|
||||
|
||||
# 输出框配置
|
||||
output_label.grid(row=4, column=0, sticky=tk.NW, pady=2)
|
||||
output_text.grid(row=4, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), pady=2)
|
||||
output_scroll.grid(row=4, column=2, sticky=(tk.N, tk.S))
|
||||
output_text["yscrollcommand"] = output_scroll.set
|
||||
|
||||
def copy_output(event):
|
||||
output = output_text.get("1.0", tk.END).strip()
|
||||
if output:
|
||||
pyperclip.copy(output)
|
||||
messagebox.showinfo("提示", "输出已复制到剪贴板")
|
||||
|
||||
output_text.bind("<Button-1>", copy_output)
|
||||
|
||||
# 添加字符串按钮
|
||||
add_button = ttk.Button(frame, text="添加字符串", command=add_input_field)
|
||||
add_button.grid(row=5, column=0, pady=5)
|
||||
|
||||
# 运行按钮
|
||||
def run():
|
||||
inputs = [text.get("1.0", tk.END).rstrip("\n") for text in input_texts]
|
||||
input_separator = input_separator_entry.get().strip()
|
||||
output_separator = output_separator_entry.get().strip()
|
||||
if len(inputs) < 2 or not all(inputs):
|
||||
messagebox.showerror("错误", "请至少输入两个非空字符串")
|
||||
return
|
||||
if not input_separator or not output_separator:
|
||||
messagebox.showerror("错误", "请输入输入和输出分隔符")
|
||||
return
|
||||
# 传递字符串和分隔符
|
||||
result = run_callback(inputs + [input_separator, output_separator])
|
||||
output_text.configure(state="normal")
|
||||
output_text.delete("1.0", tk.END)
|
||||
output_text.insert("1.0", result[0] if result else "无结果")
|
||||
output_text.configure(state="disabled")
|
||||
|
||||
# 清空按钮
|
||||
def clear():
|
||||
nonlocal output_label, output_text, output_scroll, add_button, run_button, clear_button, input_separator_entry, output_separator_entry
|
||||
# 移除多余输入框,保留两个
|
||||
while len(input_texts) > 2:
|
||||
input_texts.pop().destroy()
|
||||
input_labels.pop().destroy()
|
||||
# 清空输入和输出
|
||||
for text in input_texts:
|
||||
text.delete("1.0", tk.END)
|
||||
input_separator_entry.delete(0, tk.END)
|
||||
input_separator_entry.insert(0, ",") # 重置输入分隔符
|
||||
output_separator_entry.delete(0, tk.END)
|
||||
output_separator_entry.insert(0, ",") # 重置输出分隔符
|
||||
output_text.configure(state="normal")
|
||||
output_text.delete("1.0", tk.END)
|
||||
output_text.configure(state="disabled")
|
||||
# 重置布局
|
||||
for i, (label, text) in enumerate(zip(input_labels, input_texts)):
|
||||
label.grid(row=i, column=0, sticky=tk.NW, pady=2)
|
||||
text.grid(row=i, column=1, columnspan=2, sticky=(tk.W, tk.E), pady=2)
|
||||
update_scrollregion()
|
||||
|
||||
run_button = ttk.Button(frame, text="运行脚本", command=run)
|
||||
run_button.grid(row=6, column=0, pady=5)
|
||||
clear_button = ttk.Button(frame, text="清空", command=clear)
|
||||
clear_button.grid(row=6, column=1, sticky=tk.W, pady=5)
|
||||
|
||||
return frame
|
98
scripts/比较两个字符串的差异.py
Normal file
98
scripts/比较两个字符串的差异.py
Normal file
@ -0,0 +1,98 @@
|
||||
def process(input_strings: list) -> list:
|
||||
"""比较两个字符串的元素差异,支持自定义分隔符、数值比较和忽略微小差异"""
|
||||
try:
|
||||
if len(input_strings) != 5:
|
||||
return ["错误:输入格式不正确,期望 [str1, str2, separator, numeric_compare, ignore_tiny_diff]"]
|
||||
str1, str2, separator, numeric_compare, ignore_tiny_diff = input_strings
|
||||
numeric_compare = numeric_compare.lower() == "true"
|
||||
ignore_tiny_diff = ignore_tiny_diff.lower() == "true"
|
||||
|
||||
if not str1 or not str2:
|
||||
return ["错误:请输入两个字符串"]
|
||||
|
||||
if separator == "\\n":
|
||||
elements1 = [e.strip() for e in str1.splitlines() if e.strip()]
|
||||
elements2 = [e.strip() for e in str2.splitlines() if e.strip()]
|
||||
else:
|
||||
elements1 = [e.strip() for e in str1.split(separator) if e.strip()]
|
||||
elements2 = [e.strip() for e in str2.split(separator) if e.strip()]
|
||||
|
||||
result = []
|
||||
missing_in_1 = []
|
||||
missing_in_2 = []
|
||||
|
||||
if numeric_compare:
|
||||
try:
|
||||
nums1 = [(float(e), i + 1) for i, e in enumerate(elements1) if e.strip()]
|
||||
nums2 = [(float(e), i + 1) for i, e in enumerate(elements2) if e.strip()]
|
||||
|
||||
if ignore_tiny_diff:
|
||||
TOLERANCE = 1e-6
|
||||
set1 = set()
|
||||
set2 = set()
|
||||
for val, idx in nums1:
|
||||
found = False
|
||||
for existing_val in set1:
|
||||
if abs(existing_val - val) < TOLERANCE:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
set1.add(val)
|
||||
for val, idx in nums2:
|
||||
found = False
|
||||
for existing_val in set2:
|
||||
if abs(existing_val - val) < TOLERANCE:
|
||||
found = True
|
||||
break
|
||||
if not found:
|
||||
set2.add(val)
|
||||
for val, idx in nums2:
|
||||
matched = False
|
||||
for v1 in set1:
|
||||
if abs(v1 - val) < TOLERANCE:
|
||||
matched = True
|
||||
break
|
||||
if not matched:
|
||||
missing_in_1.append(f"{val:.6f} (位置 {idx})")
|
||||
for val, idx in nums1:
|
||||
matched = False
|
||||
for v2 in set2:
|
||||
if abs(v2 - val) < TOLERANCE:
|
||||
matched = True
|
||||
break
|
||||
if not matched:
|
||||
missing_in_2.append(f"{val:.6f} (位置 {idx})")
|
||||
else:
|
||||
set1 = {n[0] for n in nums1}
|
||||
set2 = {n[0] for n in nums2}
|
||||
for val, idx in nums2:
|
||||
if val not in set1:
|
||||
missing_in_1.append(f"{val:.6f} (位置 {idx})")
|
||||
for val, idx in nums1:
|
||||
if val not in set2:
|
||||
missing_in_2.append(f"{val:.6f} (位置 {idx})")
|
||||
except ValueError:
|
||||
return ["错误:输入包含无法转换为数值的元素"]
|
||||
else:
|
||||
set1, set2 = set(elements1), set(elements2)
|
||||
for i, e in enumerate(elements2, 1):
|
||||
if e not in set1:
|
||||
missing_in_1.append(f"{e} (位置 {i})")
|
||||
for i, e in enumerate(elements1, 1):
|
||||
if e not in set2:
|
||||
missing_in_2.append(f"{e} (位置 {i})")
|
||||
|
||||
if missing_in_1:
|
||||
result.append("字符串1相对于字符串2缺少:")
|
||||
result.extend(sorted(missing_in_1))
|
||||
else:
|
||||
result.append("字符串1相对于字符串2没少")
|
||||
if missing_in_2:
|
||||
result.append("字符串2相对于字符串1缺少:")
|
||||
result.extend(sorted(missing_in_2))
|
||||
else:
|
||||
result.append("字符串2相对于字符串1没少")
|
||||
|
||||
return ["\n".join(result)]
|
||||
except Exception as e:
|
||||
return [f"错误:{str(e)}"]
|
103
scripts/比较两个字符串的差异.ui.py
Normal file
103
scripts/比较两个字符串的差异.ui.py
Normal file
@ -0,0 +1,103 @@
|
||||
import tkinter as tk
|
||||
from tkinter import ttk
|
||||
import pyperclip
|
||||
from tkinter import messagebox
|
||||
|
||||
def create_ui(parent, run_callback):
|
||||
"""创建前端界面:两个输入框、数值比较勾选框、分隔符选择、忽略微小差异选项、输出框、运行和清空按钮"""
|
||||
frame = ttk.Frame(parent)
|
||||
frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))
|
||||
frame.columnconfigure(1, weight=1)
|
||||
frame.rowconfigure(5, weight=1)
|
||||
|
||||
ttk.Label(frame, text="比较两个字符串的元素差异").grid(
|
||||
row=0, column=0, columnspan=2, sticky=tk.W, pady=5
|
||||
)
|
||||
|
||||
ttk.Label(frame, text="字符串1:").grid(row=1, column=0, sticky=tk.W, pady=2)
|
||||
input_entry1 = tk.Text(frame, height=4, width=50)
|
||||
input_entry1.grid(row=1, column=1, sticky=(tk.W, tk.E), pady=2)
|
||||
|
||||
ttk.Label(frame, text="字符串2:").grid(row=2, column=0, sticky=tk.W, pady=2)
|
||||
input_entry2 = tk.Text(frame, height=4, width=50)
|
||||
input_entry2.grid(row=2, column=1, sticky=(tk.W, tk.E), pady=2)
|
||||
|
||||
ttk.Label(frame, text="分隔符:").grid(row=3, column=0, sticky=tk.W, pady=2)
|
||||
separator_var = tk.StringVar(value=",")
|
||||
separator_menu = ttk.OptionMenu(
|
||||
frame,
|
||||
separator_var,
|
||||
",",
|
||||
",", ";", "\\n", "空格"
|
||||
)
|
||||
separator_menu.grid(row=3, column=1, sticky=tk.W, pady=2)
|
||||
|
||||
numeric_var = tk.BooleanVar(value=False)
|
||||
ttk.Checkbutton(frame, text="启用数值比较", variable=numeric_var).grid(
|
||||
row=3, column=1, sticky=tk.E, pady=2
|
||||
)
|
||||
|
||||
ignore_tiny_diff_var = tk.BooleanVar(value=False)
|
||||
ignore_tiny_diff_check = ttk.Checkbutton(
|
||||
frame, text="忽略微小差异", variable=ignore_tiny_diff_var,
|
||||
command=lambda: numeric_var.set(True) if ignore_tiny_diff_var.get() else None
|
||||
)
|
||||
ignore_tiny_diff_check.grid(row=4, column=1, sticky=tk.E, pady=2)
|
||||
|
||||
ttk.Label(frame, text="比较结果:").grid(row=5, column=0, sticky=tk.NW, pady=2)
|
||||
output_text = tk.Text(frame, height=4, width=50, state="disabled")
|
||||
output_text.grid(row=5, column=1, sticky=(tk.W, tk.E, tk.N, tk.S), pady=2)
|
||||
output_scroll = ttk.Scrollbar(frame, orient=tk.VERTICAL, command=output_text.yview)
|
||||
output_scroll.grid(row=5, column=2, sticky=(tk.N, tk.S))
|
||||
output_text["yscrollcommand"] = output_scroll.set
|
||||
|
||||
def copy_output(event):
|
||||
output = output_text.get("1.0", tk.END).strip()
|
||||
if output:
|
||||
pyperclip.copy(output)
|
||||
messagebox.showinfo("提示", "输出已复制到剪贴板")
|
||||
|
||||
output_text.bind("<Button-1>", copy_output)
|
||||
|
||||
def run():
|
||||
input1 = input_entry1.get("1.0", tk.END).strip()
|
||||
input2 = input_entry2.get("1.0", tk.END).strip()
|
||||
if not input1 or not input2:
|
||||
messagebox.showerror("错误", "请输入两个字符串")
|
||||
return
|
||||
separator = separator_var.get()
|
||||
if separator == "空格":
|
||||
separator = " "
|
||||
try:
|
||||
input_list = [
|
||||
input1,
|
||||
input2,
|
||||
separator,
|
||||
str(numeric_var.get()).lower(),
|
||||
str(ignore_tiny_diff_var.get()).lower()
|
||||
]
|
||||
result = run_callback(input_list)
|
||||
output_text.configure(state="normal")
|
||||
output_text.delete("1.0", tk.END)
|
||||
if result and result[0]:
|
||||
output_text.insert("1.0", result[0])
|
||||
else:
|
||||
output_text.insert("1.0", "无结果")
|
||||
output_text.configure(state="disabled")
|
||||
except Exception as e:
|
||||
messagebox.showerror("错误", f"运行脚本失败:{str(e)}")
|
||||
|
||||
def clear():
|
||||
input_entry1.delete("1.0", tk.END)
|
||||
input_entry2.delete("1.0", tk.END)
|
||||
output_text.configure(state="normal")
|
||||
output_text.delete("1.0", tk.END)
|
||||
output_text.configure(state="disabled")
|
||||
numeric_var.set(False)
|
||||
ignore_tiny_diff_var.set(False)
|
||||
separator_var.set(",")
|
||||
|
||||
ttk.Button(frame, text="运行脚本", command=run).grid(row=6, column=0, pady=5)
|
||||
ttk.Button(frame, text="清空", command=clear).grid(row=6, column=1, sticky=tk.W, pady=5)
|
||||
|
||||
return frame
|
Loading…
x
Reference in New Issue
Block a user