说明
这段Python代码使用Tkinter库创建了一个图形用户界面(GUI)应用程序,名为"WorkflowEditor"。这个程序允许用户创建和编辑工作流中的功能及其参数。以下是代码的主要部分和功能:
WorkflowEditor
类:这是主类,负责设置窗口和框架,并管理功能按钮和参数编辑器。__init__
方法:初始化方法创建窗口,设置标题,并创建左侧的功能框和右侧的工作流编排框(注释掉了)。它还添加了一些示例功能,并设置了一个计数器来跟踪功能数量。add_function
方法:这个方法用于在左侧的功能框中添加一个新的功能按钮。每个按钮都可以点击编辑其参数。add_new_function
方法:这个方法通过弹出一个对话框来请求用户输入新功能的名称,然后调用add_function
方法添加新功能。edit_params
方法:这个方法用于编辑功能的参数。它创建一个ParamEditor
实例,并等待用户编辑参数。ParamEditor
类:这个类用于创建一个对话框,允许用户编辑输入和输出参数。用户可以添加、编辑和删除参数。ParamEditorNew
类:这个类与ParamEditor
类非常相似,也用于创建一个对话框,允许用户编辑输入和输出参数。这个类似乎是ParamEditor
类的副本,可能是用于实现不同的编辑功能或作为备份。on_drag_start
和on_drag_motion
函数:这两个函数实现了拖拽功能,允许用户拖拽功能按钮。if __name__ == "__main__":
:这是Python程序的入口点,它创建一个Tk
窗口实例,并创建一个WorkflowEditor
实例来启动应用程序。
这个程序的主要功能是让用户能够创建和编辑工作流中的功能及其参数。用户可以通过点击"Add Function"按钮添加新功能,然后通过点击功能按钮编辑其参数。这个程序可能用于流程自动化、脚本编写或其他需要管理功能及其参数的应用场景。
代码
python
import tkinter as tk
from tkinter import simpledialog, messagebox
class WorkflowEditor:
def __init__(self, root):
self.root = root
self.root.title("Workflow Editor")
# 创建左侧的功能框
self.functions_frame = tk.Frame(self.root, width=600, height=600, bg='white', borderwidth=2, relief="solid")
self.functions_frame.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
add_function_button = tk.Button(self.functions_frame, text="Add Function", command=self.add_new_function)
add_function_button.pack(side=tk.BOTTOM, fill=tk.BOTH)
# 创建右侧的工作流编排框
# self.workflow_frame = tk.Canvas(self.root, width=600, height=600, bg='white',borderwidth=2, relief="solid")
# self.workflow_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
# 添加一些示例功能
self.add_function('Function 1', {'input': {'param1': 'value1', 'param2': 'value2'}, 'output': {'result': ''}})
self.add_function('Function 2', {'input': {'param1': 'value1', 'param2': 'value2'}, 'output': {'result': ''}})
self.add_function('Function 3', {'input': {'param1': 'value1', 'param2': 'value2'}, 'output': {'result': ''}})
self.func_count = 3
def add_function(self, name, params):
# 创建一个功能按钮,可以点击编辑参数
functions_frame = tk.Frame(root)
functions_frame.pack()
# 创建9个按钮,并使用Grid布局管理器将它们放置在3x3的网格中
for row in range(3):
for col in range(3):
if row == 1 and col == 1:
button = tk.Button(functions_frame, text=name)
else:
button = tk.Button(functions_frame, text=f"Button {row},{col}")
button.grid(row=row, column=col, padx=5, pady=5)
button.bind('<Button-3>', lambda event, p=params: self.edit_params(p))
# button = tk.Button(self.functions_frame, text=name)
# button.pack(fill=tk.X)
functions_frame.bind("<Button-1>", on_drag_start)
functions_frame.bind("<B1-Motion>", on_drag_motion)
def add_new_function(self):
# 弹出对话框,请求用户输入新功能的名称
name = simpledialog.askstring("Function {}".format(self.func_count), "Enter function name:")
if name:
self.func_count += 1
# 创建一个默认的参数字典
params = {'input': {}, 'output': {'result': ''}}
# 添加新功能到界面
self.add_function("Function {}".format(self.func_count)+name, params)
# 打印新功能的参数,以便于调试
print(f"Added new function '{name}': {params}")
def edit_params(self, params):
# 弹出对话框,允许用户编辑参数
dialog = ParamEditor(self.root, params)
self.root.wait_window(dialog.top)
# 获取编辑后的参数
new_params = dialog.get_params()
print("Edited Parameters:", new_params)
def edit_params_new(self, params):
# 弹出对话框,允许用户编辑参数
dialog = ParamEditorNew(self.root, params)
self.root.wait_window(dialog.top)
# 获取编辑后的参数
new_params = dialog.get_params()
print("Edited Parameters:", new_params)
class ParamEditor:
def __init__(self, parent, params):
self.params = params
self.top = tk.Toplevel(parent)
self.top.title("Edit Parameters")
# 创建输入和输出标签框架
self.input_frame = tk.LabelFrame(self.top, text="Input Parameters", padx=5, pady=5)
self.input_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
self.output_frame = tk.LabelFrame(self.top, text="Output Parameters", padx=5, pady=5)
self.output_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 初始化参数字典
self.entries = {'input': {}, 'output': {}}
# 添加输入参数
for i, (key, value) in enumerate(self.params['input'].items()):
self.add_parameter_entry(self.input_frame, 'input', key, value, i)
# 添加输出参数
for i, (key, value) in enumerate(self.params['output'].items()):
self.add_parameter_entry(self.output_frame, 'output', key, value, i)
# 创建添加参数的按钮
add_input_button = tk.Button(self.input_frame, text="Add Input",
command=lambda: self.add_parameter(self.input_frame, 'input'))
add_input_button.grid(row=len(self.params['input']), columnspan=3, sticky="ew") # 使用grid而不是pack
add_output_button = tk.Button(self.output_frame, text="Add Output",
command=lambda: self.add_parameter(self.output_frame, 'output'))
add_output_button.grid(row=len(self.params['output']), columnspan=3, sticky="ew") # 使用grid而不是pack
# 创建确认按钮
ok_button = tk.Button(self.top, text="OK", command=self.ok)
ok_button.pack()
def add_parameter_entry(self, frame, param_type, key, value, row):
# 创建标签、输入框和删除按钮
label = tk.Label(frame, text=key)
entry = tk.Entry(frame)
entry.insert(0, value) # 设置默认值
delete_button = tk.Button(frame, text="X", command=lambda k=key: self.delete_parameter(frame, param_type, k))
label.grid(row=row, column=0, sticky="e")
entry.grid(row=row, column=1)
delete_button.grid(row=row, column=2)
# 将输入框添加到字典中
self.entries[param_type][key] = {'label': label, 'entry': entry, 'button': delete_button}
def add_parameter(self, frame, param_type):
# 获取新的参数名
key = simpledialog.askstring("New Parameter", "Enter parameter name:")
if key and key not in self.params[param_type]:
# 计算行号
row = len(self.entries[param_type])
# 添加参数
self.params[param_type][key] = ''
self.add_parameter_entry(frame, param_type, key, '', row)
def delete_parameter(self, frame, param_type, key):
# 删除参数输入框和按钮
entry = self.entries[param_type].pop(key)
entry['label'].grid_forget()
entry['entry'].grid_forget()
entry['button'].grid_forget()
# 从参数字典中删除参数
del self.params[param_type][key]
def ok(self):
# 更新参数并关闭对话框
for param_type in self.entries:
for key, entry_dict in self.entries[param_type].items():
self.params[param_type][key] = entry_dict['entry'].get()
self.top.destroy()
def get_params(self):
return self.params
class ParamEditorNew:
def __init__(self, parent, params):
self.params = params
self.top = tk.Toplevel(parent)
self.top.title("Edit Parameters")
# 创建输入和输出标签框架
self.input_frame = tk.LabelFrame(self.top, text="Input Parameters", padx=5, pady=5)
self.input_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
self.output_frame = tk.LabelFrame(self.top, text="Output Parameters", padx=5, pady=5)
self.output_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
# 初始化参数字典
self.entries = {'input': {}, 'output': {}}
# 添加输入参数
for i, (key, value) in enumerate(self.params['input'].items()):
self.add_parameter_entry(self.input_frame, 'input', key, value, i)
# 添加输出参数
for i, (key, value) in enumerate(self.params['output'].items()):
self.add_parameter_entry(self.output_frame, 'output', key, value, i)
# 创建添加参数的按钮
add_input_button = tk.Button(self.input_frame, text="Add Input",
command=lambda: self.add_parameter(self.input_frame, 'input'))
add_input_button.grid(row=len(self.params['input']), columnspan=3, sticky="ew") # 使用grid而不是pack
add_output_button = tk.Button(self.output_frame, text="Add Output",
command=lambda: self.add_parameter(self.output_frame, 'output'))
add_output_button.grid(row=len(self.params['output']), columnspan=3, sticky="ew") # 使用grid而不是pack
# 创建确认按钮
ok_button = tk.Button(self.top, text="OK", command=self.ok)
ok_button.pack()
def add_parameter_entry(self, frame, param_type, key, value, row):
# 创建标签、输入框和删除按钮
label = tk.Label(frame, text=key)
entry = tk.Entry(frame)
entry.insert(0, value) # 设置默认值
delete_button = tk.Button(frame, text="X", command=lambda k=key: self.delete_parameter(frame, param_type, k))
label.grid(row=row, column=0, sticky="e")
entry.grid(row=row, column=1)
delete_button.grid(row=row, column=2)
# 将输入框添加到字典中
self.entries[param_type][key] = {'label': label, 'entry': entry, 'button': delete_button}
def add_parameter(self, frame, param_type):
# 获取新的参数名
key = simpledialog.askstring("New Parameter", "Enter parameter name:")
if key and key not in self.params[param_type]:
# 计算行号
row = len(self.entries[param_type])
# 添加参数
self.params[param_type][key] = ''
self.add_parameter_entry(frame, param_type, key, '', row)
def delete_parameter(self, frame, param_type, key):
# 删除参数输入框和按钮
entry = self.entries[param_type].pop(key)
entry['label'].grid_forget()
entry['entry'].grid_forget()
entry['button'].grid_forget()
# 从参数字典中删除参数
del self.params[param_type][key]
def ok(self):
# 更新参数并关闭对话框
for param_type in self.entries:
for key, entry_dict in self.entries[param_type].items():
self.params[param_type][key] = entry_dict['entry'].get()
self.top.destroy()
def get_params(self):
return self.params
def on_drag_start(event):
"""开始拖拽"""
widget = event.widget
widget._drag_start_x = event.x
widget._drag_start_y = event.y
def on_drag_motion(event):
"""拖拽中"""
widget = event.widget
x = widget.winfo_x() - widget._drag_start_x + event.x
y = widget.winfo_y() - widget._drag_start_y + event.y
widget.place(x=x, y=y)
if __name__ == "__main__":
root = tk.Tk()
app = WorkflowEditor(root)
root.mainloop()