使用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”按钮添加新功能,然后通过点击功能按钮编辑其参数。这个程序可能用于流程自动化、脚本编写或其他需要管理功能及其参数的应用场景。

代码

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()

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/772532.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

技术探索:利用Python库wxauto实现Windows微信客户端的全面自动化管理

项目地址&#xff1a;github-wxauto 点击即可访问 项目官网&#xff1a;wxauto 点击即可访问 &#x1f602;什么是wxauto? wxauto 是作者在2020年开发的一个基于 UIAutomation 的开源 Python 微信自动化库&#xff0c;最初只是一个简单的脚本&#xff0c;只能获取消息和发送…

argparse大坑之parser

parser.add_argument(--rate,help"--rate 0.5 means that there is a 50% probability;",typefloat,default0.5)此时用-h输出usage会报错如下&#xff1a; 最后发现是因为parser的help里面出现了%&#xff0c;改了之后就好了。真坑啊&#xff01;

centos7安装mqtt服务端

下载emqx centos7安装包 https://download.csdn.net/download/qq32933432/89515118 安装 cd /opt/ mkdir emqx # 把文件上传进去 rpm -ivh emqx-centos7-4.2.7-x86_64.rpm # 运行 emqx start确保防火墙将1883和18083这两端口开启&#xff0c;可视化界面&#xff1a;http://主…

腾讯云函数部署环境[使用函数URL]

使用函数URL 之前使用的是网关API,最近腾讯云的网关API说要关闭了,所以没有办法这里改成函数URL,使用后发现只要不是在浏览器直接访问的情况,函数URL都可以满足! 这里结合腾讯云函数node.js返回自动带反斜杠这篇文章来做说明,比如这里的URL如下: 结合文章腾讯云函数node.js返…

科东软件精彩亮相华南工博会,展现未来工业前沿技术

近日&#xff0c;华南国际工业博览会在深圳成功举办。科东软件携众多前沿技术、解决方案及最新应用案例精彩亮相&#xff0c;为参展观众带来了一场工业智能的科技盛宴。 鸿道操作系统&#xff08;Intewell&#xff09; 科东软件重点展示了鸿道操作系统&#xff08;Intewell&…

幻兽帕鲁卡顿严重、延迟高怎么办?幻兽帕鲁卡顿问题处理

幻兽帕鲁更是一款支持多人游戏模式的生存制作游戏。玩家们可以邀请好友一同加入这个充满奇幻与冒险的世界&#xff0c;共同挑战强大的敌人&#xff0c;分享胜利的喜悦。在多人模式中&#xff0c;玩家之间的合作与竞争将成为游戏的一大看点。玩家们需要充分发挥自己的智慧和策略…

小白 | 华为云docker设置镜像加速器

一、操作场景 通过docker pull命令下载镜像中心的公有镜像时&#xff0c;往往会因为网络原因而需要很长时间&#xff0c;甚至可能因超时而下载失败。为此&#xff0c;容器镜像服务提供了镜像下载加速功能&#xff0c;帮助您获得更快的下载体验。 二、约束与限制 构建镜像的客…

软件开发中常用的11款bug记录、跟踪、管理系统对比【2024更新】

软件开发项目的复杂性不断增加&#xff0c;有效的bug管理变得尤为关键。对开发团队而言&#xff0c;没有什么比选择一款合适的Bug跟踪工具更重要的了。工具的功能、界面友好度、整合能力及成本都是决策的关键因素。 1、PingCode 推荐指数&#xff1a;五星 简介&#xff1a;P…

采用B/S模式 可跨平台使用的数据采集监控平台!

数据采集监控平台是一款专注于工业企业生产设备管理、数据采集、数据分析、数据管理、数据存储、数据传输等的软件系统。系统具备丰富的接口&#xff0c;配置灵活&#xff0c;方便部署&#xff0c;通过采集企业生产设备的数据集中处理&#xff0c;将各个信息孤岛有机连接&#…

【图像分割】mask2former:通用的图像分割模型详解

最近看到几个项目都用mask2former做图像分割&#xff0c;虽然是1年前的论文&#xff0c;但是其attention的设计还是很有借鉴意义&#xff0c;同时&#xff0c;mask2former参考了detr的query设计&#xff0c;实现了语义和实例分割任务的统一。 1.背景 1.1 detr简介 detr算是第…

.NET发布成单个文件后获取不到程序所在路径的问题

.net程序不发布成单个文件&#xff0c;所以运行都是正常的&#xff0c;但是发布成单个文件后发现使用&#xff1a; var basePath Path.GetDirectoryName((System.Reflection.Assembly.GetExecutingAssembly().Location)); 获取不到应用程序所在的路径了。 找一下几个获取本程…

Flutter集成高德导航SDK(Android篇)(JAVA语法)

先上flutter doctor&#xff1a; flutter sdk版本为&#xff1a;3.19.4 引入依赖&#xff1a; 在app的build.gradle下&#xff0c;添加如下依赖&#xff1a; implementation com.amap.api:navi-3dmap:10.0.700_3dmap10.0.700navi-3dmap里面包含了定位功能&#xff0c;地图功能…

Cloudflare 推出一款免费对抗 AI 机器人的可防止抓取数据工具

上市云服务提供商Cloudflare推出了一种新的免费工具&#xff0c;可防止机器人抓取其平台上托管的网站以获取数据以训练AI模型。 一些人工智能供应商&#xff0c;包括谷歌、OpenAI 和苹果&#xff0c;允许网站所有者通过修改他们网站的robots.txt来阻止他们用于数据抓取和模型训…

系统架构设计师教程(清华第2版)<第1章 绪论>解读

系统架构设计师教程 第一章 绪论 1.1 系统架构概述1.1.1 系统架构的定义及发展历程1.1.2 软件架构的常用分类及建模方法1.1.3 软件架构的应用场景1.1.4 软件架构的发展未来1.2 系统架构设计师概述1.2.1 架构设计师的定义、职责和任务1.2.2 架构设计师应具备的专业素质1.3 如何成…

Unity中TimeLine的一些用法

Unity中TimeLine的一些用法 概念其他 概念 无Track模式&#xff08;PlayableAsset、PlayableBehaviour&#xff09; 1. 两者关系 运行在PlayableTrack中作用 PlayableBehaviour 实际执行的脚本字段并不会显示在timeline面板上 PlayableAsset PlayableBehaviour的包装器&#x…

电脑彻底删除的文件还能恢复吗怎么弄 电脑删除的文件怎么恢复 回收站也删了

实测可行的文件恢复方法&#xff0c;无论是彻底删除的文件&#xff0c;还是被清空的回收站文件&#xff0c;使用该方法都可以轻松找回。整个恢复过程操作简单&#xff0c;并且绝不会损伤电脑硬件。这意味着&#xff0c;您再也不用为误删文件而焦虑了。有关电脑彻底删除的文件还…

【Windows】Bootstrap Studio(网页设计)软件介绍及安装步骤

软件介绍 Bootstrap Studio 是一款专为前端开发者设计的强大工具&#xff0c;主要用于快速创建现代化的响应式网页和网站。以下是它的主要特点和功能&#xff1a; 直观的界面设计 Bootstrap Studio 提供了直观的用户界面&#xff0c;使用户能够轻松拖放元素来构建网页。界面…

audo dl上使用tensorrt llm,baichuan7B为例

1. 在社区镜像搜索 nvidia 找一个tensorrt llm 0.10 以上的版本&#xff0c;系统盘30g安装软件应该够用&#xff0c;免费的数据盘50G用来存放模型。baichuan7B原始模型应该会占用14G&#xff0c;转换为fp16的 ckpt后再占用14G&#xff0c;build后占用14G。总共需要占用42G&…

视频太大发不出去怎么处理,视频太大发不了邮件怎么办

在数字化时代&#xff0c;视频已成为我们分享生活、传递信息的重要方式。然而&#xff0c;当遇到视频文件过大&#xff0c;无法发送或分享时&#xff0c;你是否感到困扰&#xff1f;别担心&#xff0c;本文将为你揭秘轻松解决视频太大发不了的问题。 电脑频编辑器可以用于简单的…

工业智能网关的作用有哪些?工业智能网关与传统网关的主要区别-天拓四方

工业智能网关是一种专为工业环境设计的网络设备&#xff0c;具备数据采集、传输、协议转换以及边缘计算等功能。它作为连接工业设备与互联网的关键枢纽&#xff0c;不仅实现了工业设备的互联互通&#xff0c;还通过对采集到的数据进行实时分析&#xff0c;为工业生产的智能化管…