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://www.mzph.cn/news/867557.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

UEC++ 虚幻5第三人称射击游戏(二)

UEC++ 虚幻5第三人称射击游戏(二) 派生榴弹类武器 新建一个继承自Weapon的子类作为派生榴弹类武器 将Weapon类中的Fire函数添加virtual关键字变为虚函数让榴弹类继承重写 在ProjectileWeapon中重写Fire函数,新建生成投射物的模版变量 Fire函数重写逻辑 代码//生成的投射物U…

从文本到安全图像:自动提示优化防止不当内容生成

T2I生成技术已经得到了广泛关注&#xff0c;并见证了如GLIDE、Imagen、DALL-E 2、Stable Diffusion等大型生成模型的发展。尽管这些模型能够根据文本描述生成高质量的图像&#xff0c;促进了书籍插图、品牌标识设计、游戏场景创作等多种实际应用&#xff0c;但它们也被恶意用户…

使用京东云主机搭建幻兽帕鲁游戏联机服务器全流程,0基础教程

使用京东云服务器搭建幻兽帕鲁Palworld游戏联机服务器教程&#xff0c;非常简单&#xff0c;京东云推出幻兽帕鲁镜像系统&#xff0c;镜像直接选择幻兽帕鲁镜像即可一键自动部署&#xff0c;不需要手动操作&#xff0c;真正的新手0基础部署幻兽帕鲁&#xff0c;阿腾云整理基于京…

Python学习笔记30:进阶篇(十九)pygame的使用之显示与窗口管理

前言 基础模块的知识通过这么长时间的学习已经有所了解&#xff0c;更加深入的话需要通过完成各种项目&#xff0c;在这个过程中逐渐学习&#xff0c;成长。 我们的下一步目标是完成python crash course中的外星人入侵项目&#xff0c;这是一个2D游戏项目。在这之前&#xff…

YOLOv8改进 | 注意力机制 | 结合静态和动态上下文信息的注意力机制

秋招面试专栏推荐 &#xff1a;深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 &#x1f4a1;&#x1f4a1;&#x1f4a1;本专栏所有程序均经过测试&#xff0c;可成功执行&#x1f4a1;&#x1f4a1;&#x1f4a1; 专栏目录 &#xff1a;《YOLOv8改进有效…

力扣双指针算法题目:双数之和,三数之和,四数之和

目录 一&#xff1a;双数之和 1.题目&#xff1a; 2.思路解析 3.代码 二&#xff1a;三数之和 1.题目 2.思路解析 3&#xff0c;代码 三&#xff1a;四数字之和 1.题目 2.思路解析 3.代码 一&#xff1a;双数之和 1.题目&#xff1a; 输入一个递增排序的数组和一…

贵州建筑三类人员安全员2024年考试最新题库练习题

一、单选题 1.建设工程安全管理的方针是&#xff08;&#xff09;。 A.安全第一&#xff0c;预防为主&#xff0c;综合治理 B.质量第一&#xff0c;兼顾安全 C.安全至上 D.安全责任重于泰山 答案&#xff1a;A 2.安全生产管理的根本目的是&#xff08;&#xff09;。 A.…

Lunaproxy与711Proxy的对比与优劣分析

今天我们来深入对比两款在市场上备受关注的代理IP服务&#xff1a;Lunaproxy和711Proxy。接下来&#xff0c;我们将从多个角度对这两款服务进行详细分析&#xff0c;帮助大家做出明智的选择。 优势分析 711Proxy的优势 1. 性价比高&#xff1a;711Proxy提供多种灵活的套餐选…

伪元素content追加文字使用小技巧

E::before和E::after本身的作用是追加字&#xff0c;直接在文字后面追加链接 <!DOCTYPE html> <html lang"zh-cn"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-sca…

AI文本转语音,再也不用担心视频配音了.

文章目录 简介代码实现调用开通百度付费包 简介 背景 我想要将文本,转为语音,然后配上图片,这样就可以很快生成一个视频. 可以说是配音吧,我还是比较喜欢通过代码来自动化.所以今天就来实现一下,同时做一下分享和记录.目标 通过python代码,自动将文本转为配音.平台 我选择了百…

万界星空科技MES系统中的排版排产功能

在当今高度竞争的市场环境中&#xff0c;企业对于生产管理的效率和质量要求日益提高。作为智能制造的重要组成部分&#xff0c;制造执行系统&#xff08;MES&#xff09;以其强大的功能&#xff0c;在提升企业生产能力方面发挥着不可替代的作用。万界星空科技作为行业领先的智能…

MongoDB集群搭建-最简单

目录 前言 一、分片概念 二、搭建集群的步骤 总结 前言 MongoDB分片&#xff08;Sharding&#xff09;是一种水平扩展数据库的方法&#xff0c;它允许将数据分散存储在多个服务器上&#xff0c;从而提高数据库的存储容量和处理能力。分片是MongoDB为了应对大数据量和高吞吐量需…

Science期刊政策反转:允许生成式AI用于论文写作,意味着什么?

我是娜姐 迪娜学姐 &#xff0c;一个SCI医学期刊编辑&#xff0c;探索用AI工具提效论文写作和发表。 关于各大top期刊和出版社对于生成式AI用于论文写作中的规定&#xff0c;娜姐之前写过一篇文章&#xff1a; 如何合理使用AI写论文&#xff1f;来看Top 100学术期刊和出版社的…

深度解析 Raft 分布式一致性协议

本文参考转载至&#xff1a;浅谈 Raft 分布式一致性协议&#xff5c;图解 Raft - 白泽来了 - 博客园 (cnblogs.com) 深度解析 Raft 分布式一致性协议 - 掘金 (juejin.cn) raft-zh_cn/raft-zh_cn.md at master maemual/raft-zh_cn (github.com) 本篇文章将模拟一个KV数据读写服…

【漏洞复现】禅道——未授权登入(QVD-2024-15263)

声明&#xff1a;本文档或演示材料仅供教育和教学目的使用&#xff0c;任何个人或组织使用本文档中的信息进行非法活动&#xff0c;均与本文档的作者或发布者无关。 文章目录 漏洞描述漏洞复现测试工具 漏洞描述 禅道&#xff08;Zentao&#xff09;是一款开源的项目管理和协作…

死锁-活锁与活锁的预防、死锁与死锁的预防和检测(处理死锁的方式:事务等待图)

一、引言 1、死锁是因采用封锁技术实现并发控制而产生的一种运行事务被阻塞或等待的现象 2、如果利用严格两阶段封锁协议来解决我们前面提到的“更新丢失”这种数据不一致问题&#xff0c;非串行调度中的事务T1首先获得数据对象X上的读锁并开始执行&#xff0c;随后事务T2也获…

数值分析笔记(五)线性方程组解法

三角分解法 A的杜利特分解公式如下&#xff1a; u 1 j a 1 j ( j 1 , 2 , ⋯ , n ) , l i 1 a i 1 / u 11 ( i 2 , 3 , ⋯ , n ) , u k j a k j − ∑ m 1 k − 1 l b m u m j ⇒ a k j ( j k , k 1 , ⋯ , n ) , l i k ( a i k − ∑ m 1 k − 1 l i n u m k ) /…

uniapp 在手机上导出excel

1.创建excelDev.js文件 export default {exportExcel(fileData, documentName excel) {plus.io.requestFileSystem(plus.io.PUBLIC_DOCUMENTS, function(fs) {let rootObj fs.rootlet fullPath rootObj.fullPathconsole.log("开始导出数据")// 创建文件夹rootObj…

破解宇宙终极奥秘,战胜昊天无上束缚

在幽邃的暗夜下&#xff0c;细品着夫子与昊天跨越千年的智勇交锋&#xff0c;我的思绪不禁飘向了更加深远的宇宙边际&#xff0c;回响起那些关于人类如何挑战天命、战胜上天的过往。 宇宙奥秘 在浩瀚无垠的宇宙深渊中&#xff0c;隐藏着一段超越凡尘的规则。昊天&#xff0c;…

2025湖北武汉智慧教育装备信息化展/智慧校园展/湖北高博会

2025武汉教育装备展,2025武汉智慧教育展,2025武汉智慧校园展,2025武汉教育信息化展,2025武汉智慧教室展,湖北智慧校园展,湖北智慧教室展,武汉教学设备展,湖北高教会,湖北高博会 2025湖北武汉智慧教育装备信息化展/智慧校园展/湖北高博会 2025第10届武汉国际教育装备及智慧校园…