当前位置: 首页 > news >正文

python ui 工作流完善功能

说明

这段代码是一个使用Tkinter编写的图形用户界面(GUI)应用程序,它用于编辑工作流。以下是代码的主要部分和功能的说明:

  1. Tooltip类:这是一个自定义类,用于创建一个工具提示窗口,当鼠标悬停在指定的Tkinter小部件上时显示。它使用Tkinter的Toplevel窗口来创建工具提示,并且当鼠标离开时销毁这个窗口。
  2. WorkflowEditor类:这是应用程序的主类,它负责创建和布局窗口,添加功能按钮,并处理与按钮相关的操作。它包含一个函数add_function,用于在功能框中添加新按钮,并设置它们的位置和功能。
  3. ParamEditorParamEditorNew类:这两个类是参数编辑器,它们是弹出窗口,允许用户编辑工作流中函数的参数。ParamEditor用于编辑函数名和功能参数名,而ParamEditorNew用于编辑输入/输出方向和参数名。
  4. on_drag_starton_drag_motion函数:这些函数用于处理鼠标拖拽事件,允许用户拖拽功能框中的按钮并改变它们的位置。
  5. if __name__ == "__main__":块:这是Python脚本的入口点,它创建一个主窗口,并实例化WorkflowEditor类,启动Tkinter的事件循环。
    整个应用程序的设计是为了提供一个工作流编辑器,用户可以添加、编辑和拖拽功能按钮,以及编辑每个功能按钮的参数。工具提示的添加是为了提供额外的信息,以便用户更好地理解每个功能按钮的作用。

代码

import tkinter as tk
from tkinter import simpledialog, ttkclass Tooltip:def __init__(self, widget, text):self.widget = widgetself.text = textself.widget.bind("<Enter>", self.enter)self.widget.bind("<Leave>", self.leave)self.tooltip_window = Nonedef enter(self, event=None):x, y, _, _ = self.widget.bbox("insert")x += self.widget.winfo_rootx() + 25y += self.widget.winfo_rooty() + 25self.tooltip_window = tk.Toplevel(self.widget)self.tooltip_window.wm_overrideredirect(True)self.tooltip_window.wm_geometry(f"+{x}+{y}")label = ttk.Label(self.tooltip_window, text=self.text, background="#ffffe0", borderwidth=1, relief="solid")label.pack()def leave(self, event=None):if self.tooltip_window:self.tooltip_window.destroy()self.tooltip_window = Noneclass WorkflowEditor:def __init__(self, root):self.root = rootself.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)self.functions_frame_list = dict()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('Function1', {'input': {'param1': 'value1', 'param2': 'value2'}, 'output': {'result': ''}})self.add_function('Function2', {'input': {'param1': 'value1', 'param2': 'value2'}, 'output': {'result': ''}})self.add_function('Function3', {'input': {'param1': 'value1', 'param2': 'value2'}, 'output': {'result': ''}})self.func_count = 3def add_function(self, name, params):# 创建一个功能按钮,可以点击编辑参数functions_frame = tk.Frame(self.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)button.widgetName = "{}_{}".format(row, col)button.grid(row=row, column=col, padx=5, pady=5)button.bind('<Button-3>', lambda event, p=params, r=row, c=col: self.edit_params(p, name, r, c))else:button = tk.Button(functions_frame, text=f"edit")button.widgetName = "{}_{}".format(row, col)button.grid(row=row, column=col, padx=5, pady=5)button.bind('<Button-3>', lambda event, p=params, r=row, c=col: self.edit_params_new(p, name, r, c))# 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)self.functions_frame_list[name] = functions_framedef 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, name, r, c):# 弹出对话框,允许用户编辑参数dialog = ParamEditor(self.root, params)dialog.name = nameself.root.wait_window(dialog.top)# 获取编辑后的参数# new_params = dialog.get_params()# 增加函数功能说明Tooltip(self.functions_frame_list[name].children["!button{}".format(r * 3 + c + 1)],params["func_name"]+":"+params["tip"])# 设置颜色  设计名字self.functions_frame_list[name].children["!button{}".format(r * 3 + c + 1)].config(bg=params["arg"])def edit_params_new(self, params, name, r, c):print(name)# 弹出对话框,允许用户编辑参数dialog = ParamEditorNew(self.root, params)dialog.name = namedialog.r = rdialog.c = cself.root.wait_window(dialog.top)# 获取编辑后的参数# new_params = dialog.get_params()colors = ['red', 'blue', 'green', 'yellow', 'purple', 'orange', 'cyan', 'pink', 'brown']# self.functions_frame.children[0].config(bg=colors[1])# self.functions_frame.children["!button"].config(bg=colors[1])if r * 3 + c + 1 == 1:self.functions_frame_list[name].children["!button"].config(bg=params["arg"])self.functions_frame_list[name].children["!button"].config(text=params["s"])else:self.functions_frame_list[name].children["!button{}".format(r * 3 + c + 1)].config(bg=params["arg"])self.functions_frame_list[name].children["!button{}".format(r * 3 + c + 1)].config(text=params["s"])class ParamEditor:def __init__(self, parent, params):self.params = paramsself.top = tk.Toplevel(parent)self.top.title("参数编辑")# 创建输入和输出标签框架self.input_frame = tk.LabelFrame(self.top, text="函数名", 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="功能参数名", padx=5, pady=5)self.output_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)# self.output_frame1 = tk.LabelFrame(self.top, text="输入/输出参数名", padx=5, pady=5)# self.output_frame1.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)# 添加输入参数self.add_parameter_entry(self.input_frame)# 添加输出参数# self.add_parameter_option(self.output_frame, tk.StringVar(), options=["io_选项A", "io_选项B", "io_选项C", "io_选项D"])self.add_parameter_text(self.output_frame)# 创建确认按钮ok_button = tk.Button(self.top, text="OK", command=self.ok)ok_button.pack()def add_parameter_entry(self, frame):if self.params.get("func_name") is None:self.entry = tk.Entry(frame)self.entry.pack()else:self.entry = tk.Entry(frame, textvariable=self.params["func_name"])self.entry.pack()def add_parameter_text(self, frame):self.text_box = tk.Text(frame, height=10, width=50)self.text_box.pack()def ok(self):# 更新参数并关闭对话框self.params["func_name"] = self.entry.get()self.params["tip"] = self.text_box.get("1.0", tk.END)self.top.destroy()return self.paramsclass ParamEditorNew:def __init__(self, parent, params):self.params = paramsself.top = tk.Toplevel(parent)self.top.title("参数编辑")# 创建输入和输出标签框架self.input_frame = tk.LabelFrame(self.top, text="输入/输出方向", 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="输入/输出参数名", padx=5, pady=5)self.output_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)# self.output_frame1 = tk.LabelFrame(self.top, text="输入/输出参数名", padx=5, pady=5)# self.output_frame1.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)# 添加输入参数self.add_parameter_option(self.input_frame, tk.StringVar(), options=["s_^", "s_v", "s_<", "s_>"])# 添加输出参数# self.add_parameter_option(self.output_frame, tk.StringVar(), options=["io_选项A", "io_选项B", "io_选项C", "io_选项D"])self.add_parameter_option(self.output_frame, tk.StringVar(),options=["arg_"+i for i in ['red', 'blue', 'green', 'yellow', 'purple', 'orange', 'cyan', 'pink', 'brown']])# 创建确认按钮ok_button = tk.Button(self.top, text="OK", command=self.ok)ok_button.pack()def on_select_option(self, selected_var):# 当用户选择一个OptionMenu时,这个函数会被调用def callback(value):print(f"你选择了:{value}")self.params[value.split("_")[0]] = value.split("_")[1]return callbackdef add_parameter_option(self, frame, selected_var, options=["选项A", "选项B", "选项C", "选项D"]):# 设置一个默认值selected_var.set("请选择")# 创建下拉单选菜单dropdown = tk.OptionMenu(frame, selected_var, *options, command=self.on_select_option(selected_var))dropdown.pack()def ok(self):# 更新参数并关闭对话框self.top.destroy()def get_params(self):return self.paramsdef on_drag_start(event):"""开始拖拽"""widget = event.widgetwidget._drag_start_x = event.xwidget._drag_start_y = event.ydef on_drag_motion(event):"""拖拽中"""widget = event.widgetx = widget.winfo_x() - widget._drag_start_x + event.xy = widget.winfo_y() - widget._drag_start_y + event.ywidget.place(x=x, y=y)if __name__ == "__main__":root = tk.Tk()app = WorkflowEditor(root)root.mainloop()

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • HTTP 常见状态码
  • STM32F1+HAL库+FreeTOTS学习2——STM32移植FreeRTOS
  • 详解前缀码与前缀编码
  • Redis---10---SpringBoot集成Redis
  • (void) (_x == _y)的作用
  • 白嫖A100活动-入门篇-1.Linux+InterStudio
  • C语言从头学30——字符串
  • C#/WPF 自制截图工具
  • ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法
  • 陈志泊主编《数据库原理及应用教程第4版微课版》的实验题目参考答案实验2
  • Nuxt3 的生命周期和钩子函数(十一)
  • 【十三】图解 Spring 核心数据结构:BeanDefinition 其二
  • Poker Game, Run Fast
  • 【C++】模板进阶--保姆级解析(什么是非类型模板参数?什么是模板的特化?模板的特化如何应用?)
  • 基于Python爬虫的城市二手房数据分析可视化
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • IE9 : DOM Exception: INVALID_CHARACTER_ERR (5)
  • ES6 ...操作符
  • Git同步原始仓库到Fork仓库中
  • iOS | NSProxy
  • JavaScript函数式编程(一)
  • javascript面向对象之创建对象
  • Java教程_软件开发基础
  • macOS 中 shell 创建文件夹及文件并 VS Code 打开
  • 大主子表关联的性能优化方法
  • 基于Javascript, Springboot的管理系统报表查询页面代码设计
  • 前端相关框架总和
  • 前嗅ForeSpider采集配置界面介绍
  • 物联网链路协议
  • 新版博客前端前瞻
  • 阿里云服务器购买完整流程
  • ​14:00面试,14:06就出来了,问的问题有点变态。。。
  • $.proxy和$.extend
  • (3)(3.2) MAVLink2数据包签名(安全)
  • (3)nginx 配置(nginx.conf)
  • (libusb) usb口自动刷新
  • (Matalb分类预测)GA-BP遗传算法优化BP神经网络的多维分类预测
  • (第61天)多租户架构(CDB/PDB)
  • (二刷)代码随想录第16天|104.二叉树的最大深度 559.n叉树的最大深度● 111.二叉树的最小深度● 222.完全二叉树的节点个数
  • (附源码)springboot 智能停车场系统 毕业设计065415
  • (附源码)springboot高校宿舍交电费系统 毕业设计031552
  • (剑指Offer)面试题41:和为s的连续正数序列
  • (力扣)循环队列的实现与详解(C语言)
  • (全注解开发)学习Spring-MVC的第三天
  • (图文详解)小程序AppID申请以及在Hbuilderx中运行
  • (一)springboot2.7.6集成activit5.23.0之集成引擎
  • (已解决)Bootstrap精美弹出框模态框modal,实现js向modal传递数据
  • (转)程序员疫苗:代码注入
  • .net 4.0发布后不能正常显示图片问题
  • .NET 线程 Thread 进程 Process、线程池 pool、Invoke、begininvoke、异步回调
  • .net6 当连接用户的shell断掉后,dotnet会自动关闭,达不到长期运行的效果。.NET 进程守护
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .NET周刊【7月第4期 2024-07-28】
  • @cacheable 是否缓存成功_Spring Cache缓存注解
  • @PreAuthorize与@Secured注解的区别是什么?