Python tkinter 初探Toplevel控件搭建父子窗口

目录

Toplevel控件搭建父子窗口

最简明的父子窗口框架

改进一:屏蔽和开放按钮

改进二:子窗口始终在主窗口之上

改进三:增加子窗口的关闭协议

改进四:使子窗口长获焦点

总结


Toplevel控件搭建父子窗口

最近,用Python给单位里用的“智慧食堂”系统编制了一个餐卡充值文件生成器,自动匹配餐卡号并快速生成导入数据用的Excel表格,截图如下:

使用tkinter Toplevel控件弹出子窗口,用作设置备注的子窗口。在编程过程中,边学边写探索到不少新知识,简单介绍如下:

最简明的父子窗口框架

创建一个主窗口、一个子窗口,各放一个按钮,代码如下:

import win32api, tkinter as tkdef _toplevel():top = tk.Toplevel(root)top.title("Toplevel Window")W,H=400,300top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')btn_Close = tk.Button(top, text="Close", command=top.destroy)btn_Close.pack()  if __name__=='__main__':# 创建主窗口root = tk.Tk()root.title("Main Window")# 获取windows系统桌面分辨率X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1)W,H=600,480root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')# 创建一个打开Toplevel窗口的按钮btn_Open = tk.Button(root, text="Open Toplevel", command=_toplevel)btn_Open.pack()# 运行Tkinter事件循环root.mainloop()

上述代码的缺点是主窗口上的Open按钮可以反复点击打开多个子窗口,要想办法按需要来屏蔽它的点击功能。

改进一:屏蔽和开放按钮

以下代码可以调整按钮的使用状态:tk.DISABLED、tk.NORMAL

button.config(state=tk.DISABLED)
button.config(state=tk.NORMAL)

打开子窗口时,Open按钮的状态改为tk.DISABLED,此时已无法点击了。

import win32api, tkinter as tk  class TopWindow:def __init__(self, parent):  top = self.top = tk.Toplevel(parent)top.title("Toplevel Window")W,H=400,300top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')btn_Close = tk.Button(top, text="Close", command=self.on_close)btn_Close.pack()def on_close(self):btn_Open.config(state=tk.NORMAL)self.top.destroy()def on_open():TopWindow(root)btn_Open.config(state=tk.DISABLED)if __name__=='__main__':  root = tk.Tk()  root.title("Main Window")  X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1)W,H=600,480root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')btn_Open = tk.Button(root, text="Open Toplevel", command=on_open)btn_Open.pack()root.mainloop()

改进二:子窗口始终在主窗口之上

top.transient(root)  # 设置Toplevel窗口始终在主窗口root的上方

import win32api, tkinter as tk  class TopWindow:def __init__(self, parent):  top = self.top = tk.Toplevel(parent)top.title("Toplevel Window")W,H=400,300top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')top.transient(root) # 设置Toplevel窗口始终在主窗口上方btn_Close = tk.Button(top, text="Close", command=self.on_close)btn_Close.pack()def on_close(self):btn_Open.config(state=tk.NORMAL)self.top.destroy()def on_open():TopWindow(root)btn_Open.config(state=tk.DISABLED)if __name__=='__main__':  root = tk.Tk()  root.title("Main Window")  X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1)W,H=600,480root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')btn_Open = tk.Button(root, text="Open Toplevel", command=on_open)btn_Open.pack()root.mainloop()

另外一种方法也能设置子窗口永远在前:

top.wm_attributes('-topmost', True)  # 设置Toplevel窗口在所有窗口的上方

两种方法的区别在于后者是全局的设置,它使得子窗口在操作系统中所有窗口的上面,包括其它应用程序的窗口。

如下图,请比较一下与上一张截图的效果有啥区别:

改进三:增加子窗口的关闭协议

如下图,直接点击子窗口右上关闭按钮,只触发窗口默认的top.destroy事件。这样关闭子窗口后,主窗口的按钮状态并不能恢复;以下代码使得子窗口的"WM_DELETE_WINDOW"关闭协议绑定了自定义的关闭事件self.onclose:

top.protocol("WM_DELETE_WINDOW", self.on_close)

完整代码如下:

import win32api, tkinter as tk  class TopWindow:def __init__(self, parent):  top = self.top = tk.Toplevel(parent)top.title("Toplevel Window")W,H=400,300top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')top.transient(root)top.protocol("WM_DELETE_WINDOW", self.on_close)btn_Close = tk.Button(top, text="Close", command=self.on_close)btn_Close.pack()def on_close(self):btn_Open.config(state=tk.NORMAL)self.top.destroy()def on_open():TopWindow(root)btn_Open.config(state=tk.DISABLED)if __name__=='__main__':  root = tk.Tk()  root.title("Main Window")  X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1)W,H=600,480root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')btn_Open = tk.Button(root, text="Open Toplevel", command=on_open)btn_Open.pack()root.mainloop()

改进四:使子窗口长获焦点

top.grab_set()  # 确保Toplevel窗口长获焦点

使用这个方法,前面提到的按钮状态的切换以及子窗口绑定关闭协议的代码都不需要了,非常简洁。top.grab_set() 配合 top.transient(root) 共同使用(如下标注红色部分),效果最佳:

import win32api, tkinter as tk 

class TopWindow:
    def __init__(self, parent):  
        top = self.top = tk.Toplevel(parent)
        top.title("Toplevel Window")
        W,H=400,300
        top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')
        top.grab_set()
        top.transient(root)

        btn_Close = tk.Button(top, text="Close", command=top.destroy)
        btn_Close.pack()

def on_open():
    TopWindow(root)

if __name__=='__main__':  

    root = tk.Tk()  
    root.title("Main Window")  
    X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1)
    W,H=600,480
    root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')

    btn_Open = tk.Button(root, text="Open Toplevel", command=on_open)
    btn_Open.pack()
    root.mainloop()


源代码复制框如下:

import win32api, tkinter as tk  class TopWindow:def __init__(self, parent):  top = self.top = tk.Toplevel(parent)top.title("Toplevel Window")W,H=400,300top.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')top.grab_set()top.transient(root)btn_Close = tk.Button(top, text="Close", command=top.destroy)btn_Close.pack()def on_open():TopWindow(root)if __name__=='__main__':  root = tk.Tk()  root.title("Main Window")  X,Y=win32api.GetSystemMetrics(0),win32api.GetSystemMetrics(1)W,H=600,480root.geometry(f'{W}x{H}+{(X-W)//2}+{(Y-H)//2}')btn_Open = tk.Button(root, text="Open Toplevel", command=on_open)btn_Open.pack()root.mainloop()

总结

通过对toplevel控件的编程操练,掌握了tkinter子窗口的调用方法,了解了topleve的多种特殊方法、响应事件以及绑定协议。

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

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

相关文章

【PostgreSQL】从零开始:(十三)PostgreSQL-SQL语句操作架构(模式) Schema

Schema概述 PostgreSQL 数据库集群包含一个或多个命名数据库。角色和一些其他对象类型在整个集群中共享。与服务器的客户端连接只能访问单个数据库中的数据,该数据库在连接请求中指定。 用户不一定有权访问集群中的每个数据库。共享角色名称意味着不能在同一集群中…

【C++】POCO学习总结(十八):XML

【C】郭老二博文之&#xff1a;C目录 1、XML文件格式简介 1&#xff09;XML文件的开头一般都有个声明&#xff0c;声明是可选 <&#xff1f;xml version"1.0" encoding"UTF-8"?>2&#xff09;根元素&#xff1a;XML文件最外层的元素 3&#xff…

【C++】封装:练习案例-设计立方体类

练习案例&#xff1a;设计立方体类 设计立方体类(Cube) 求出立方体的面积和体积 分别用全局函数和成员函数判断两个立方体是否相等。 思路&#xff1a; 1&#xff09;创建立方体类 2&#xff09;设计属性 长&#xff0c;高&#xff0c;宽 3&#xff09;设计行为 获取立方…

在Windows上通过VS2019自带的Cmake来编译OpenCV-4.5.3源码

文章目录 用VS打开OpenCV源码cmake的配置及生成操作生成及安装 用VS打开OpenCV源码 方式一&#xff1a;文件–》打开–》Cmake 找到源码根目录下CMakeLists.txt文件 导入即可。 方式二&#xff1a;在开始使用这里 选择 打开本地文件夹 找到源码的根目录&#xff0c;导入即可…

IDEA中,如何将maven项目变为SpringBoot项目?

第一步&#xff1a;新建Maven工程 这很简单不做过多赘述。 第二步&#xff1a;修改pom.xml文件 分别加入springboot父依赖&#xff0c;web依赖&#xff0c;test测试依赖&#xff0c;maven打包依赖。 <?xml version"1.0" encoding"UTF-8"?> <…

5.5 Linux Apache服务

1、概念介绍 a. Web 服务简介 WEB服务器也称为WWW(WORLD WIDE WEB&#xff0c;万维网)服务器&#xff0c;主要功能是提供网上信息浏览服务。 常用web服务器&#xff1a;httpd&#xff08;apache&#xff09;、nginx、tomcat、IIS 客户端&#xff1a;IE、firefox、chrome b…

PyTorch官网demo解读——第一个神经网络(2)

上一篇&#xff1a;PyTorch官网demo解读——第一个神经网络&#xff08;1&#xff09; 继上一篇文章我们展示了第一个神经网络的完整代码&#xff0c;今天我们来聊聊这个神经网络的模型设计。 这个demo实际上只使用了一个简单的线性模型&#xff1a;y wx b&#xff1b; 手写…

5.2 Linux FTP 服务

1、概念介绍 FTP&#xff08;File Transfer Protocol:文件传输协议&#xff09;作用Internet 上用来传送文件的协议 FTP Server&#xff08;File Transfer Protocol Server&#xff09;是在互联网/局域网上提供文件存储和访问服务的计算机&#xff0c;它们依照FTP协议提供服务…

【MySQL】数据库和表的操作

数据库和表的操作 一、数据库的操作1. 创建数据库2. 字符集和校验规则&#xff08;1&#xff09;查看系统默认字符集以及校验规则&#xff08;2&#xff09;查看数据库支持的字符集&#xff08;3&#xff09;查看数据库支持的字符集校验规则&#xff08;4&#xff09;校验规则对…

《点云处理》平面拟合

前言 在众多点云处理算法中&#xff0c;其中关于平面拟合的算法十分广泛。本篇内容主要是希望总结归纳各类点云平面拟合算法&#xff0c;并且将代码进行梳理保存。 环境&#xff1a; VS2019 PCL1.11.1 1.RANSAC 使用ransac对平面进行拟合是非常常见的用法&#xff0c;PCL…

音频I2S

前言 基于网上资料对相关概念做整理汇总&#xff0c;部分内容引用自文后文章。 学习目标&#xff1a;简单了解相关概念、相关协议。 1 概述 数字音频接口DAI&#xff0c;即Digital Audio Interfaces&#xff0c;顾名思义&#xff0c;DAI表示在板级或板间传输数字音频信…

【STM32】STM32学习笔记-EXTI外部中断(11)

00. 目录 文章目录 00. 目录01. 中断系统02. 中断执行流程03. STM32中断04. NVIC基本结构05. NVIC优先级分组06. EXTI简介07. EXTI基本结构08. AFIO复用IO口09. EXTI框图10. 计数器模块11. 旋转编码器简介12. 附录 01. 中断系统 中断&#xff1a;在主程序运行过程中&#xff0…