这是一个win10中运行的一个名叫通达信参数清洗的python程序,通过tktinter输入参数,界面尺寸600*250,底色淡黄色,一键处理的按键是糖果绿色,请合理布局,字体:仿宋,字号12号。
界面有输入框用于输入,每次点击时若检测到剪切板有内容自动写入输入框。请熟悉了解通达信的参数设置格式。点击运行键时,自动将各种内容精准的转化为标准格式。
界面增加在顶部显示选项,默认选中,选中后程序一直在除了右键菜单之外的其他程序顶部显示
输入内容一般有字母或字母加数字构成,其参数有三个数字,之间以一些空格或其他符号等各种间隔。点击运行后转换为N:=5;这样的标准格式标准格式。点击运行按键 之后,如果正常处理,不提示错误,则自动复制结果到剪切板。
以下是各种内容的示例:
{ P1(2 20 5) P2(2 20 4)}
P1:1.10.5
P2:1.10.4
SHORT 5/30/7 LONG 10/250/19
N 1 200 3 M 1 200 8
N. 2. 90 9 N1. 2 30 3 N2. 2 30 3
{M1 2 1000 3
M2 2 1000 6
M3 2 1000 12
M4 2 1000 24 }
{P1,-20,20,-6}
点击运行后转为:
P1:=;P2:4;
P1:=5;
P2:=4;
SHORT:=7;LONG:=19;
N:=3:M:=8;
N:=9;N1:=3;N2:=3;
M1:=3:
M2:=6;
M3:=12;
M4:=24;
P1:=-6;
"""
通达信参数清洗工具 - TDX Param Cleaner
功能:将各种格式的通达信指标参数转换为标准格式 N:=5;
支持的输入格式:
-
{ P1(2 20 5) P2(2 20 4)}
-
P1:1.10.5
-
SHORT 5/30/7 LONG 10/250/19
-
N 1 200 3 M 1 200 8
-
N. 2. 90 9 N1. 2 30 3
-
多行格式等
输出格式:
-
P1:=5;P2:=4;
-
SHORT:=7;LONG:=19;
-
等标准格式
"""
import tkinter as tk
from tkinter import ttk, messagebox
import re
import pyperclip
import threading
class TDXParamCleaner:
"""通达信参数清洗工具类"""
def init(self, root):
"""初始化工具"""
self.root = root
self.root.title("通达信参数清洗")
self.root.geometry("310x200")
self.root.resizable(False, False)
设置界面属性
self.setup_ui()
初始设置置顶
self.root.attributes('-topmost', True)
绑定窗口焦点事件,当窗口被点击激活时检查剪贴板
self.root.bind('<FocusIn>', lambda e: self.check_clipboard())
检查剪贴板内容
self.check_clipboard()
def setup_ui(self):
"""设置用户界面"""
设置主窗口背景色
self.root.configure(bg="#FFF9C4") # 淡黄色背景
创建主框架
main_frame = tk.Frame(self.root, bg="#FFF9C4")
main_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=10)
创建顶部选项框架
top_frame = tk.Frame(main_frame, bg="#FFF9C4")
top_frame.pack(fill=tk.X, pady=(0, 5))
创建标题
title_label = tk.Label(
top_frame,
text="注意对比",
font=("仿宋", 12, "bold"),
bg="#FFF9C4",
fg="#5D4037"
)
title_label.pack(side=tk.LEFT, padx=(0, 5))
添加置顶选项
self.always_on_top_var = tk.BooleanVar(value=True)
always_on_top_check = tk.Checkbutton(
top_frame,
text="置顶",
variable=self.always_on_top_var,
font=("仿宋", 10),
bg="#FFF9C4",
fg="#5D4037",
activebackground="#FFF9C4",
activeforeground="#5D4037",
command=self.toggle_always_on_top
)
always_on_top_check.pack(side=tk.LEFT, padx=(0, 5))
运行按钮(糖果绿色)
self.run_button = tk.Button(
top_frame,
text="转换",
command=self.process_params,
font=("宋体", 11),#, "bold"
bg="#81C784", # 糖果绿色
fg="#FFFFFF",
activebackground="#66BB6A",
activeforeground="#FFFFFF",
relief=tk.RAISED,
bd=3,
padx=5,
pady=4,
cursor="hand2"
)
self.run_button.pack(side=tk.LEFT, padx=(0, 5))
清空按钮
self.clear_button = tk.Button(
top_frame,
text="清空",
command=self.clear_input,
font=("宋体", 11),
bg="#FFB74D",
fg="#FFFFFF",
activebackground="#FFA726",
activeforeground="#FFFFFF",
relief=tk.RAISED,
bd=2,
padx=5,
pady=4,
cursor="hand2"
)
self.clear_button.pack(side=tk.LEFT, padx=(0, 5))
复制按钮
self.copy_button = tk.Button(
top_frame,
text="复制",
command=self.copy_result,
font=("宋体", 11),
bg="#64B5F6",
fg="#FFFFFF",
activebackground="#42A5F5",
activeforeground="#FFFFFF",
relief=tk.RAISED,
bd=2,
padx=5,
pady=4,
cursor="hand2",
state=tk.DISABLED
)
self.copy_button.pack(side=tk.LEFT)
添加提示内容(可选择可复制)
hint_var = tk.StringVar(value="DRAWTEXT(CROSS(,),,'');")
hint_entry = tk.Entry(
main_frame,
textvariable=hint_var,
font=("仿宋", 11),
bg="#FFF9C4",
fg="#6D4C41",
borderwidth=0,
justify=tk.CENTER
)
hint_entry.config(state='readonly')
hint_entry.pack(pady=(0, 5), fill=tk.X)
创建输入区域
input_frame = tk.Frame(main_frame, bg="#FFF9C4")
input_frame.pack(fill=tk.X, pady=(0, 5))
输入文本框
self.input_text = tk.Text(
input_frame,
font=("仿宋", 12),
width=70,
height=4,
bg="#FFFFFF",
fg="#000000",
wrap=tk.WORD,
borderwidth=2,
relief=tk.GROOVE
)
self.input_text.pack(fill=tk.X, expand=True)
创建输出区域
output_frame = tk.Frame(main_frame, bg="#FFF9C4")
output_frame.pack(fill=tk.X)
输出文本框(可选择可复制)
self.output_text = tk.Text(
output_frame,
font=("仿宋", 12),
width=70,
height=3,
bg="#FFFFFF",
fg="#000000",
wrap=tk.WORD,
borderwidth=2,
relief=tk.GROOVE
)
self.output_text.pack(fill=tk.X, expand=True)
设置为只读但可选择
self.output_text.config(state='normal')
添加只读效果但保持可选择
self.output_text.bind('<Key>', lambda e: 'break')
def toggle_always_on_top(self):
"""切换窗口置顶状态"""
try:
self.root.attributes('-topmost', self.always_on_top_var.get())
except Exception as e:
切换失败,静默处理
pass
def check_clipboard(self):
"""检查剪贴板内容并自动填充"""
try:
直接在主线程中检查剪贴板,避免线程问题
clipboard_content = pyperclip.paste()
if clipboard_content.strip():
先清空输入框,再插入剪贴板内容
self.input_text.delete(1.0, tk.END)
self.input_text.insert(tk.END, clipboard_content)
except Exception as e:
剪贴板访问失败,静默处理
pass
def process_params(self):
"""处理参数转换"""
input_text = self.input_text.get(1.0, tk.END).strip()
if not input_text:
messagebox.showwarning("警告", "请输入参数内容!")
return
try:
处理参数
result = self.clean_params(input_text)
显示结果
self.output_text.delete(1.0, tk.END)
self.output_text.insert(tk.END, result)
启用复制按钮
self.copy_button.config(state=tk.NORMAL)
自动复制结果到剪贴板
if result:
try:
pyperclip.copy(result)
except Exception as e:
复制失败,静默处理
pass
except Exception as e:
messagebox.showerror("错误", f"处理失败: {str(e)}")
def clean_params(self, text):
"""清洗参数的核心逻辑"""
results = []
try:
处理各种格式
格式1: { P1(2 20 5) P2(2 20 4)}
pattern1 = r'(\w+)\s*\(([^)]+)\)'
matches1 = re.findall(pattern1, text)
for match in matches1:
name = match[0].strip()
params = re.findall(r'-?\d+', match[1])
if len(params) >= 3:
results.append(f"{name}:={params[2]};")
格式1a: {P1,-20,20,-6} (逗号分隔格式)
pattern1a = r'(\w+)\s*[,,]\s*(-?\d+)\s*[,,]\s*(-?\d+)\s*[,,]\s*(-?\d+)'
matches1a = re.findall(pattern1a, text)
for match in matches1a:
name = match[0].strip()
if len(match) >= 4:
results.append(f"{name}:={match[3]};")
格式2: P1:1.10.5 或 P1:1,10,5
pattern2 = r'(\w+)\s*[:=]\s*([\d\.\s,/]+)'
matches2 = re.findall(pattern2, text)
for match in matches2:
name = match[0].strip()
params = re.findall(r'\d+', match[1])
if len(params) >= 3:
results.append(f"{name}:={params[2]};")
格式3: SHORT 5/30/7 LONG 10/250/19
格式4: N 1 200 3 M 1 200 8
格式5: N. 2. 90 9 N1. 2 30 3
lines = text.split('\n')
for line in lines:
提取所有单词和数字
tokens = re.findall(r'\w+', line)
i = 0
while i < len(tokens):
if tokens[i].isalpha() or (tokens[i][-1] == '.' and tokens[i][:-1].isalpha()):
找到参数名
name = tokens[i].rstrip('.')
查找后面的数字
nums = []
for j in range(i + 1, min(i + 4, len(tokens))):
if tokens[j].isdigit():
nums.append(tokens[j])
else:
break
if len(nums) >= 3:
results.append(f"{name}:={nums[2]};")
i += len(nums) + 1
else:
i += 1
else:
i += 1
处理多行格式
如:
M1 2 1000 3
M2 2 1000 6
M3 2 1000 12
M4 2 1000 24
lines = text.split('\n')
for line in lines:
line = line.strip()
if line:
parts = re.findall(r'\S+', line)
if len(parts) >= 4 and parts[0].isalpha():
name = parts[0].rstrip('.')
if parts[3].isdigit():
results.append(f"{name}:={parts[3]};")
移除重复项
seen = set()
unique_results = []
for item in results:
if item not in seen:
seen.add(item)
unique_results.append(item)
合并结果
return ''.join(unique_results)
except Exception as e:
处理过程中出现异常,返回空字符串
return ""
def clear_input(self):
"""清空输入框"""
self.input_text.delete(1.0, tk.END)
self.output_text.delete(1.0, tk.END)
self.copy_button.config(state=tk.DISABLED)
def copy_result(self):
"""复制结果到剪贴板"""
try:
result = self.output_text.get(1.0, tk.END).strip()
if result:
try:
pyperclip.copy(result)
messagebox.showinfo("成功", "结果已复制到剪贴板!")
except Exception as e:
messagebox.showerror("错误", "复制失败,请手动复制!")
else:
messagebox.showwarning("警告", "没有可复制的内容!")
except Exception as e:
messagebox.showerror("错误", "获取结果失败!")
if name == "main":
root = tk.Tk()
app = TDXParamCleaner(root)
root.mainloop()