使用tkinter 制作工作流ui

说明

这段Python代码使用Tkinter库创建了一个图形用户界面(GUI)应用程序,名为"WorkflowEditor"。这个程序允许用户创建和编辑工作流中的功能及其参数。以下是代码的主要部分和功能:

  1. WorkflowEditor类:这是主类,负责设置窗口和框架,并管理功能按钮和参数编辑器。
  2. __init__方法:初始化方法创建窗口,设置标题,并创建左侧的功能框和右侧的工作流编排框(注释掉了)。它还添加了一些示例功能,并设置了一个计数器来跟踪功能数量。
  3. add_function方法:这个方法用于在左侧的功能框中添加一个新的功能按钮。每个按钮都可以点击编辑其参数。
  4. add_new_function方法:这个方法通过弹出一个对话框来请求用户输入新功能的名称,然后调用add_function方法添加新功能。
  5. edit_params方法:这个方法用于编辑功能的参数。它创建一个ParamEditor实例,并等待用户编辑参数。
  6. ParamEditor类:这个类用于创建一个对话框,允许用户编辑输入和输出参数。用户可以添加、编辑和删除参数。
  7. ParamEditorNew类:这个类与ParamEditor类非常相似,也用于创建一个对话框,允许用户编辑输入和输出参数。这个类似乎是ParamEditor类的副本,可能是用于实现不同的编辑功能或作为备份。
  8. on_drag_starton_drag_motion函数:这两个函数实现了拖拽功能,允许用户拖拽功能按钮。
  9. 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()
相关推荐
Amd79415 分钟前
Nuxt.js 应用中的 webpack:compiled 事件钩子
前端·webpack·开发·编译·nuxt.js·事件·钩子
生椰拿铁You24 分钟前
09 —— Webpack搭建开发环境
前端·webpack·node.js
Sxiaocai27 分钟前
使用 PyTorch 实现并训练 VGGNet 用于 MNIST 分类
pytorch·深度学习·分类
shansjqun33 分钟前
教学内容全覆盖:航拍杂草检测与分类
人工智能·分类·数据挖掘
狸克先生35 分钟前
如何用AI写小说(二):Gradio 超简单的网页前端交互
前端·人工智能·chatgpt·交互
baiduopenmap1 小时前
百度世界2024精选公开课:基于地图智能体的导航出行AI应用创新实践
前端·人工智能·百度地图
系统之家装机大师1 小时前
Win11 22H2/23H2系统11月可选更新KB5046732发布!
windows·电脑
loooseFish1 小时前
小程序webview我爱死你了 小程序webview和H5通讯
前端
系统之家装机大师1 小时前
微软发布Win11 24H2系统11月可选更新KB5046740!
windows·电脑
菜牙买菜1 小时前
让安卓也能玩出Element-Plus的表格效果
前端