tkinter绘制组件(44)——浮出ui控件

tkinter绘制组件(44)——浮出ui控件

  • 引言
  • 布局
    • 函数结构
    • ui框架
    • 对齐方向
    • 绑定已有控件
    • 出现和隐藏逻辑
    • 出现和隐藏动画
    • 完整代码函数
  • 效果
    • 测试代码
    • 最终效果
  • github项目
  • pip下载

引言

TinUI的浮出ui控件(flyout)其实是一个之间创建在UI框架内的完整BasicTinUI类,且已经绑定了TinUIXml。该控件并不之间占有窗口句柄,因此可以大量创建,包括但不限于:

  1. 弹出已有控件的说明
  2. 绑定已有控件,弹出某个操作、用法的说明
  3. 绑定已有控件,弹出简单的内部对话框或说明

从上面罗列的使用场景可以看出,flyout就是用来作为窗口内提示与简单交互的,只不过是一个轻量的UI框架,和TinUI的内嵌ui控件(ui)非常类似,只不过绑定在了已有的控件。


布局

函数结构

def add_flyout(self, fid, width:int=250, height:int=150, bind='<Button-1>', line='#dcdcdc', bg='#f9f9f9', anchor='n'):# 绘制一个浮出ui控件# 注意,默认布局在fid正上方"""fid::绑定控件的uidwidth::宽度height::高度bind::绑定的事件line::边框颜色bg::背景颜色anchor::展开方向"""

ui框架

上文说过,flyout本质就是一个BasicTinUI。

ui = BasicTinUI(self, bg=bg, highlightbackground=line, highlightthickness=1, relief='flat')
uixml = TinUIXml(ui)

对齐方向

由于是弹出控件,因此flyout的anchor不再代表控件本身的对齐方向,而是指布局在绑定控件的那一侧。比如n就代表正上方,nw代表左上方。

bbox = self.bbox(fid)
if anchor == 'nw':x = bbox[0] - 4y = bbox[1] - 4_anchor = 'se'dxy = (1, 1)
elif anchor == 'n':x = (bbox[0] + bbox[2]) / 2y = bbox[1] - 4_anchor ='s'dxy = (0, 1)
elif anchor == 'ne':x = bbox[2] + 4y = bbox[1] - 4_anchor = 'sw'dxy = (1, 1)
elif anchor == 'e':x = bbox[2] + 4y = (bbox[1] + bbox[3]) / 2_anchor = 'w'dxy = (1, 0)
elif anchor =='se':x = bbox[2] + 4y = bbox[3] + 4_anchor = 'nw'dxy = (1, 1)
elif anchor =='s':x = (bbox[0] + bbox[2]) / 2y = bbox[3] + 4_anchor = 'n'dxy = (0, 1)
elif anchor =='sw':x = bbox[0] - 4y = bbox[3] + 4_anchor = 'ne'dxy = (1, 1)
elif anchor == 'w':x = bbox[0] - 4y = (bbox[1] + bbox[3]) / 2_anchor = 'e'dxy = (1, 0)
else:# 默认为centerx = (bbox[0] + bbox[2]) / 2y = (bbox[1] + bbox[3]) / 2_anchor = 'center'dxy = (1, 1)
uid = self.create_window(x, y, width=width, height=height, window=ui, anchor=_anchor)

dxy稍后解释

绑定已有控件

self.itemconfig(uid, state='hidden')
self.tag_bind(fid, bind, show)

出现和隐藏逻辑

出现逻辑很显然,就是对于绑定控件的绑定事件,默认就是左键单击。

对于隐藏逻辑,我能够想到的就是左键单击本UI框架,这样做可以减少对其他不确定元素的依赖,且BasicTinUI本身不对单击做出响应,也不应该对单击做出响应(窗口单击获得焦点是系统层决定,这不影响)。单击本UI框架收回flyout是比较合理的。

def show(e):self.tag_unbind(fid, bind)# 避免接下来绑定self <button-1>事件时同步触发self.itemconfig(uid, state='normal')motion(None, 1)self.after(100, go_to_bind)# 避免直接触发控件点击事件
def go_to_bind():self.bind('<Button-1>', hide)
def hide(e):self.unbind('<Button-1>')self.tag_bind(fid, bind, show)motion(None, -1)self.itemconfig(uid, state='hidden')

注意上面代码片段中的两个注释内容,简单来说就是避免绑定控件左键单击和本UI框架左键单击同时触发,导致showhide调用混乱。

出现和隐藏动画

这就涉及到前文提到的dxy,且内容就是x和y方向,需要变化的为1,不需要变化的为0。

此外,motion函数的dis参数为1表示展开,-1表示收缩。

def motion(e, dis):# 展开/收缩动画# dxy为动画方向,0为不变,1为变化if dis == 1:# 展开_width = width * (1-dxy[0])_height = height * (1-dxy[1])dwidth = width / 10 * dxy[0]dheight = height / 10 * dxy[1]else:# 收缩_width = width_height = heightdwidth = -width / 10 * dxy[0]dheight = -height / 10 * dxy[1]for _ in range(10):time.sleep(0.01)_width += dwidth_height += dheightself.itemconfig(uid, width=_width, height=_height)self.update_idletasks()

完整代码函数

def add_flyout(self, fid, width:int=250, height:int=150, bind='<Button-1>', line='#dcdcdc', bg='#f9f9f9', anchor='n'):# 绘制一个浮出ui控件# 注意,默认布局在fid正上方def show(e):self.tag_unbind(fid, bind)# 避免接下来绑定self <button-1>事件时同步触发self.itemconfig(uid, state='normal')motion(None, 1)self.after(100, go_to_bind)# 避免直接触发控件点击事件def go_to_bind():self.bind('<Button-1>', hide)def hide(e):self.unbind('<Button-1>')self.tag_bind(fid, bind, show)motion(None, -1)self.itemconfig(uid, state='hidden')def motion(e, dis):# 展开/收缩动画# dxy为动画方向,0为不变,1为变化if dis == 1:# 展开_width = width * (1-dxy[0])_height = height * (1-dxy[1])dwidth = width / 10 * dxy[0]dheight = height / 10 * dxy[1]else:# 收缩_width = width_height = heightdwidth = -width / 10 * dxy[0]dheight = -height / 10 * dxy[1]for _ in range(10):time.sleep(0.01)_width += dwidth_height += dheightself.itemconfig(uid, width=_width, height=_height)self.update_idletasks()ui = BasicTinUI(self, bg=bg, highlightbackground=line, highlightthickness=1, relief='flat')uixml = TinUIXml(ui)# 围绕fid进行布局bbox = self.bbox(fid)if anchor == 'nw':x = bbox[0] - 4y = bbox[1] - 4_anchor = 'se'dxy = (1, 1)elif anchor == 'n':x = (bbox[0] + bbox[2]) / 2y = bbox[1] - 4_anchor ='s'dxy = (0, 1)elif anchor == 'ne':x = bbox[2] + 4y = bbox[1] - 4_anchor = 'sw'dxy = (1, 1)elif anchor == 'e':x = bbox[2] + 4y = (bbox[1] + bbox[3]) / 2_anchor = 'w'dxy = (1, 0)elif anchor =='se':x = bbox[2] + 4y = bbox[3] + 4_anchor = 'nw'dxy = (1, 1)elif anchor =='s':x = (bbox[0] + bbox[2]) / 2y = bbox[3] + 4_anchor = 'n'dxy = (0, 1)elif anchor =='sw':x = bbox[0] - 4y = bbox[3] + 4_anchor = 'ne'dxy = (1, 1)elif anchor == 'w':x = bbox[0] - 4y = (bbox[1] + bbox[3]) / 2_anchor = 'e'dxy = (1, 0)else:# 默认为centerx = (bbox[0] + bbox[2]) / 2y = (bbox[1] + bbox[3]) / 2_anchor = 'center'dxy = (1, 1)uid = self.create_window(x, y, width=width, height=height, window=ui, anchor=_anchor)self.itemconfig(uid, state='hidden')self.tag_bind(fid, bind, show)return ui, uixml, hide, uid

效果

测试代码

flylabel = b.add_label((1500,500),text='点击展开浮出UI')[-1]
_, flyxml, flyhide, _ = b.add_flyout(flylabel)
flyxml.funcs['flyhide']=flyhide
flyxml.loadxml('''<tinui><line><paragraph text='浮出UI'></paragraph></line><line><paragraph text='add_flyout(fid, anchor="...")'></paragraph></line><line><paragraph text='使用hide关闭'></paragraph></line>
<line><button2 text='关闭浮出UI控件' command="self.funcs['flyhide']"></button2>
</line></tinui>''')

最终效果

在这里插入图片描述


github项目

TinUI的github项目地址

pip下载

pip install tinui

🔆tkinter创新🔆

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

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

相关文章

【Unity3D】《跳舞的线》游戏的方块单方向拉伸实现案例

通过网盘分享的文件&#xff1a;CubeMoveMusic.unitypackage 链接: https://pan.baidu.com/s/1Rq-HH4H9qzVNtpQ84WXyUA?pwda7xn 提取码: a7xn 运行游戏点击空格动态创建拉伸的方块&#xff0c;由Speed控制速度&#xff0c;新方向是随机上下左右生成。 using System.Collect…

新版IDEA创建数据库表

这是老版本的IDEA创建数据库表&#xff0c;下面可以自己勾选Not null&#xff08;非空),Auto inc&#xff08;自增长),Unique(唯一标识)和Primary key&#xff08;主键) 这是新版的IDEA创建数据库表&#xff0c;Not null和Auto inc可以看得到&#xff0c;但Unique和Primary key…

jmeter中对接口进行循环请求后获取相应数据

1、工作中遇到一个场景就是对某个单一接口进行循环请求&#xff0c;并需要获取每次请求后返回的相应数据&#xff1b; 2、首先就在jmeter对接口相关组件进行配置&#xff0c;需要组件有&#xff1a;循环控制器、CSV数据文件设置、计数器、访问接口、HTTP信息头管理器、正则表达…

【含代码】逆向获取 webpack chunk 下的__webpack_require__ 函数,获悉所有的模块以及模块下的函数

背景 Webpack 打包后的代码是不会直接暴露 __webpack_require__ 函数&#xff0c;目的是为了避免污染全局变量同时也为了保护 webpack 的打包后的模块都隐藏在闭包函数里&#xff0c;达到数据的安全性。 而有时我们为了测试某个函数&#xff0c;想直接获取这个内置函数&#…

最新常见的图数据库对比,选型,架构,性能对比

图数据库排名 地址&#xff1a;https://db-engines.com/en/ranking/graphdbms 知识图谱查询语言 SPARQL、Cypher、Gremlin、PGQL 和 G-CORE 语法 / 语义 / 特性 SPARQL Cypher Gremlin PGQL G-CORE 图模式匹配查询 语法 CGP CGP CGP(无可选)1 CGP CGP 语义 子…

CentOS7使用源码安装PHP8教程整理

CentOS7使用源码安装PHP8教程整理 下载安装包解压下载的php tar源码包安装所需的一些依赖扩展库安装前的配置修改配置文件1、进入php8的安装包 配置环境变量开机自启启动服务创建软连接常见问题1、checking for icu-uc > 50.1 icu-io icu-i18n... no2、configure: error: Pa…

php-phar打包避坑指南2025

有很多php脚本工具都是打包成phar形式&#xff0c;使用起来就很方便&#xff0c;那么如何自己做一个呢&#xff1f;也找了很多文档&#xff0c;也遇到很多坑&#xff0c;这里就来总结一下 phar安装 现在直接装yum php-cli包就有phar文件&#xff0c;很方便 可通过phar help查看…

博睿数据获中国信通院泰尔终端实验室致谢!

近日&#xff0c;博睿数据收到中国信息通信研究院&#xff08;以下简称“中国信通院”&#xff09;的感谢信&#xff0c;信中对博睿数据积极参与信通院牵头的“铸基计划——高质量数字化转型推进行动”&#xff0c;并在新技术研究、标准建设、课题共创、专家智库等多项工作中提…

分布式理解

分布式 如何理解分布式 狭义的分布是指&#xff0c;指多台PC在地理位置上分布在不同的地方。 分布式系统 分布式系**统&#xff1a;**多个能独立运行的计算机&#xff08;称为结点&#xff09;组成。各个结点利用计算机网络进行信息传递&#xff0c;从而实现共同的“目标或者任…

centos哪个版本建站好?centos最稳定好用的版本

在信息化飞速发展的今天&#xff0c;服务器操作系统作为构建网络架构的基石&#xff0c;其稳定性和易用性成为企业和个人用户关注的重点。CentOS作为一款广受欢迎的开源服务器操作系统&#xff0c;凭借其强大的性能、出色的稳定性和丰富的软件包资源&#xff0c;成为众多用户建…

计算机网络 (58)无线局域网WLAN

前言 无线局域网WLAN&#xff08;Wireless Local Area Network&#xff09;是一种利用无线通信技术将计算机设备互联起来&#xff0c;构成可以互相通信和实现资源共享的网络体系。 一、定义与特点 定义&#xff1a; WLAN通过无线信道代替有线传输介质连接两个或多个设备形成一个…

vim 中粘贴内容时提示: -- (insert) VISUAL --

目录 问题现象&#xff1a;解决方法&#xff1a;问题原因&#xff1a; 问题现象&#xff1a; 使用 vim 打开一个文本文件&#xff0c;切换到编辑模式后&#xff0c;复制内容进行粘贴时有以下提示&#xff1a; 解决方法&#xff1a; 在命令行模式下禁用鼠标支持 :set mouse …

总结与展望,龙蜥社区第 30 次运营委员会会议线上召开

2025 年 1 月 20 日&#xff0c;龙蜥社区召开了第 30 次运营委员会线上会议&#xff0c;来自 24 家理事单位的 22 位委员及委员代表出席&#xff0c;本次会议由运营委员凝思软件李晨斌主持。会上总结和回顾了龙蜥社区 1 月运营发展情况&#xff0c;同步了龙蜥社区 3 大运营目标…

新型人工智能“黑帽”工具:GhostGPT带来的威胁与挑战

生成式人工智能的发展既带来了有益的生产力转型机会&#xff0c;也提供了被恶意利用的机会。 最近&#xff0c;Abnormal Security的研究人员发现了一个专门为网络犯罪创建的无审查AI聊天机器人——GhostGPT&#xff0c;是人工智能用于非法活动的新前沿&#xff0c;可以被用于网…

智能体0门槛开发

分享一个智能体开发流程。 2025 年啊&#xff0c;好多专家还有行业报告都觉得这是智能体&#xff08;AI Agent&#xff09;应用的头一年。相关的应用在商业、工业、消费等好些领域都到了关键的时候&#xff0c;这意味着从实验室走向大规模实际应用的重要转变。而且呢&#xff0…

计算机网络 (53)互联网使用的安全协议

一、SSL/TLS协议 概述&#xff1a; SSL&#xff08;Secure Sockets Layer&#xff09;安全套接层和TLS&#xff08;Transport Layer Security&#xff09;传输层安全协议是工作在OSI模型应用层的安全协议。SSL由Netscape于1994年开发&#xff0c;广泛应用于基于万维网的各种网络…

grafana新增email告警

选择一个面板 比如cpu 新增一个临界点表达式 input选A 就是A的值达到某个临界点 触发告警 我这边IS ABOVE0.15就是cpu大于0.15%就触发报警&#xff0c;这个值怎么填看指标的值显示 这里要设置一下报警条件 这边随便配置下 配置标签和通知&#xff0c;选择你的邮件 看下告警…

npm常见报错整理

npm install时报UNMET PEER DEPENDENCY 现象 npm install时报UNMET PEER DEPENDENCY,且执行npm install好几遍仍报这个。 原因 不是真的缺少某个包,而是安装的依赖版本不对,警告你应该安装某一个版本。 真的缺少某个包。 解决 看了下package.json文件,我的react是有的…

24_游戏启动逻辑梳理总结

首先这个项目从游戏根入口GameRoot.cs的初始化开始 分为 服务层初始化Svc.cs 与 业务系统层初始化Sys.cs 而服务层 分为 资源加载服务层ResSvc.cs 与 音乐播放服务层AudioSvc.cs 而在 资源加载服务层ResSvc.cs中 初始化了 名字的 配置文件 而音乐播放服务层AudioSvc.cs 暂时没…

UE求职Demo开发日志#8 强化前置条件完善,给物品加图标

1 强化前置条件完善 StrengthManager里实现一个Check前置的函数 bool CheckPreAllIsActive(int index)&#xff0c;所有的前置都已经激活就返回true&#xff0c;否则返回false 之后在强化的时候加入条件检查&#xff1a; 1.所有前置技能全部激活 2.本身没有强化过 最后测…