Python基础之tabview
以前写过界面,但是没有记录下来,以至于现在得从头学习一次,论做好笔记的重要性。
现在学习的是怎么写一个tabview出来,也就是用tkinter做一个界面切换的效果。参考链接:https://blog.csdn.net/yingshukun/article/details/89150105
tabview.py
import tkinter as tk
import tkinter.ttk as ttk class TabView(tk.Frame):
_tabs = []
_tab_view = []
_tab_text = []
_current = 0 # 当前选中tab的索引
_generate_func = None
_select_listen = None
_remove_listen = None '''
select_listen: tab选中事件回调函数,回调函数包含一个index参数
remove_listen: tab删除事件回调函数,返回值必须是一个布尔值,True表示删除,反之不删除
generate_body: 生成body控件的回调函数,返回值应该是一个widget,用于添加到body中
''' def __init__(self, master=None, select_listen=None,
remove_listen=None, generate_body=None, cnf=None, **kw):
super().__init__(master, cnf, **kw)
# 选项卡
self._top = tk.Frame(self)
self._top.bind("<Double-Button-1>", self._tab_add)
self._top.pack(fill="x") # 分割线
ttk.Separator(self, orient=tk.HORIZONTAL).pack(fill="x") # 主体view
self._bottom = tk.Frame(self)
self._bottom.pack(fill="both", expand="yes")
self._photo = tk.PhotoImage(file="remove.gif") # 事件回调
if select_listen:
if callable(select_listen):
self._select_listen = select_listen
else:
raise Exception("select_action is not callable") if remove_listen:
if callable(remove_listen):
self._remove_listen = remove_listen
else:
raise Exception("remove_action is not callable") if generate_body:
if callable(generate_body):
self._generate_func = generate_body
else:
raise Exception("generate_body is not callable") # 添加选项卡
def add_tab(self, view, text):
self._add_body(view)
self._create_tab(text) # 删除选项卡
def remove_tab(self, index):
self._tab_text.pop(index) self._tabs[index].destroy()
self._tab_view[index].destroy() self._tabs.pop(index)
self._tab_view.pop(index) if index > 0:
self._current = index - 1
self._active() @property
def body(self):
return self._bottom def _create_tab(self, text):
# 选项卡单元
tab_container = tk.Frame(self._top, relief=tk.RAISED, bd=1) # 标题、删除按钮
_tab_text_view = tk.Label(tab_container, text=text, padx=8)
_tab_remove_view = tk.Label(tab_container, image=self._photo) _tab_text_view.bind("<Button-1>", self._tab_click)
_tab_remove_view.bind("<Button-1>", self._tab_remove) _tab_text_view.pack(side=tk.LEFT)
_tab_remove_view.pack(side=tk.LEFT)
tab_container.pack(side=tk.LEFT)
self._tab_text.append(_tab_text_view)
self._tabs.append(tab_container)
self._active() def _add_body(self, view):
self._tab_view.append(view)
view.place(relwidth=1.0, relheight=1.0) # 刷新当前激活状态
def _active(self):
for i, item in enumerate(self._tabs):
if i == self._current:
item.config(relief=tk.RAISED, bd=3)
# lift方法,让当前widget处于最顶层
self._tab_view[self._current].lift()
else:
item.config(bd=1) def _tab_add(self, event):
self._current = len(self._tabs)
if not self._generate_func:
self.add_tab(tk.Frame(self.body), "Untitled")
else:
self.add_tab(self._generate_func(), "Untitled") # 删除事件回调
def _tab_remove(self, event):
current_widget = event.widget.winfo_parent()
select_index = self._index(current_widget) is_remove = True
if self._remove_listen:
is_remove = self._remove_listen(select_index) if is_remove:
if select_index != -1:
self.remove_tab(select_index) # 选项卡点击事件回调
def _tab_click(self, event):
current_widget = event.widget.winfo_parent()
select_index = self._index(current_widget)
if select_index != -1:
self._current = select_index
self._active() if self._select_listen:
self._select_listen(select_index) # 返回当前选项卡的索引
def _index(self, el):
index = [i for i, x in enumerate(self._tabs) if str(x) == el]
return index[0] if index else -1
对于上面tabview的类,或许会有不太明白的地方,一一解析。
1. Frame
frame其实就像一个布局,一个一个的分区,然后分别往上面添加控件。
2. Bind
绑定事件,比如鼠标单击,双击时需要操作什么
这两个详细的可以参考:https://www.cnblogs.com/sunzebo/articles/9643620.html
3. callable()函数
callable() 函数用于检查一个对象是否是可调用的。如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。链接:https://www.runoob.com/python/python-func-callable.html
Python基础之tabview的更多相关文章
- python之最强王者(2)——python基础语法
背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...
- Python开发【第二篇】:Python基础知识
Python基础知识 一.初识基本数据类型 类型: int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位 ...
- Python小白的发展之路之Python基础(一)
Python基础部分1: 1.Python简介 2.Python 2 or 3,两者的主要区别 3.Python解释器 4.安装Python 5.第一个Python程序 Hello World 6.P ...
- Python之路3【第一篇】Python基础
本节内容 Python简介 Python安装 第一个Python程序 编程语言的分类 Python简介 1.Python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum) ...
- 进击的Python【第三章】:Python基础(三)
Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...
- 进击的Python【第二章】:Python基础(二)
Python基础(二) 本章内容 数据类型 数据运算 列表与元组的基本操作 字典的基本操作 字符编码与转码 模块初探 练习:购物车程序 一.数据类型 Python有五个标准的数据类型: Numbers ...
- Python之路【第一篇】python基础
一.python开发 1.开发: 1)高级语言:python .Java .PHP. C# Go ruby c++ ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...
- python基础之day1
Python 简介 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Python为我们提供了非常完善的基础代码库,覆盖了 ...
- python基础之文件读写
python基础之文件读写 本节内容 os模块中文件以及目录的一些方法 文件的操作 目录的操作 1.os模块中文件以及目录的一些方法 python操作文件以及目录可以使用os模块的一些方法如下: 得到 ...
随机推荐
- 记一次项目中解决 -- 并发减库存超卖问题过程(Java)
起因:项目中要做预约功能,首先每天的余票都是有上限的,自然不能出现超卖的情况 基于我们项目是单体分布式的springcloud部署,我想了下 第一种方法,直接mysql加行锁,要update这条库存数 ...
- Redis 面试题 - 收藏版 (持续更新、吐血推荐)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- 消息队列面试题、RabbitMQ面试题、Kafka面试题、RocketMQ面试题 (史上最全、持续更新、吐血推荐)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- 来了!STM32移植LuatOS,潘多拉示例全新教程
进击的五月,继上期<使用Air724UG制作简易贪吃蛇>教程之后,@打盹的消防车 又为大家带来基于STM32的潘多拉LuatOS移植全新教程: 为什么使用潘多拉作为教程呢? STM32不能 ...
- Bootstrap中宽度大于指定宽度时有空白的解决方法
<div class="container-fluid"></div> 其中container-fluid的作用是占100%
- 使用Git将代码上传至Gitee码云中
Git是一个开源的分布式版本控制系统,可以高效处理任何或小或大的项目 Git与常用的版本控制工具CVS.Subversion 不同,Git采用了分布式版本库的方式,不必服务器端软件支持 Git与SVN ...
- 15 自动发布Java项目(Tomcat)
#!/bin/bash export PAHT=/usr/local/maven/bin:/usr/local/jdk/bin:/usr/local/sbin:/usr/local/bin:/usr/ ...
- 2018-10-14普及模拟赛」Hash 键值 (hash)
今天,带大家看一看一道思维题... Hash 键值 (hash) 题目描述 Marser沉迷hash无法自拔,然而他发现自己记不住hash键值了-- Marser使用的hash函数是一个单纯的取模运算 ...
- 信息论估计工具jidt基本使用
JIDT基本介绍 JIDT是 Java Information Dynamics Toolkit的简称,用于研究复杂系统中信息论相关度量的计算,它是一个基于java的开源工具库,也可以在Matlab. ...
- CentOS-Docker安装RabbitMQ(单点)
这里注意获取镜像的时候要获取management版本的,不要获取last版本的,management版本的才带有管理界面. 获取镜像 $ docker pull rabbitmq:management ...