以前写过界面,但是没有记录下来,以至于现在得从头学习一次,论做好笔记的重要性。

现在学习的是怎么写一个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的更多相关文章

  1. python之最强王者(2)——python基础语法

    背景介绍:由于本人一直做java开发,也是从txt开始写hello,world,使用javac命令编译,一直到使用myeclipse,其中的道理和辛酸都懂(请容许我擦干眼角的泪水),所以对于pytho ...

  2. Python开发【第二篇】:Python基础知识

    Python基础知识 一.初识基本数据类型 类型: int(整型) 在32位机器上,整数的位数为32位,取值范围为-2**31-2**31-1,即-2147483648-2147483647 在64位 ...

  3. Python小白的发展之路之Python基础(一)

    Python基础部分1: 1.Python简介 2.Python 2 or 3,两者的主要区别 3.Python解释器 4.安装Python 5.第一个Python程序 Hello World 6.P ...

  4. Python之路3【第一篇】Python基础

    本节内容 Python简介 Python安装 第一个Python程序 编程语言的分类 Python简介 1.Python的由来 python的创始人为吉多·范罗苏姆(Guido van Rossum) ...

  5. 进击的Python【第三章】:Python基础(三)

    Python基础(三) 本章内容 集合的概念与操作 文件的操作 函数的特点与用法 参数与局部变量 return返回值的概念 递归的基本含义 函数式编程介绍 高阶函数的概念 一.集合的概念与操作 集合( ...

  6. 进击的Python【第二章】:Python基础(二)

    Python基础(二) 本章内容 数据类型 数据运算 列表与元组的基本操作 字典的基本操作 字符编码与转码 模块初探 练习:购物车程序 一.数据类型 Python有五个标准的数据类型: Numbers ...

  7. Python之路【第一篇】python基础

    一.python开发 1.开发: 1)高级语言:python .Java .PHP. C#  Go ruby  c++  ===>字节码 2)低级语言:c .汇编 2.语言之间的对比: 1)py ...

  8. python基础之day1

    Python 简介 Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. Python为我们提供了非常完善的基础代码库,覆盖了 ...

  9. python基础之文件读写

    python基础之文件读写 本节内容 os模块中文件以及目录的一些方法 文件的操作 目录的操作 1.os模块中文件以及目录的一些方法 python操作文件以及目录可以使用os模块的一些方法如下: 得到 ...

随机推荐

  1. 如果在num1的任何位置有一个数字的连续三倍,并且在num2中有一个数字的连续两倍,则返回1。 如果不是这样,则返回0

    ''' 它接受数字num1和num2,如果在num1的任何位置有一个数字的连续三倍,并且在num2中有一个数字的连续两倍,则返回1. 如果不是这样,则返回0 例子 triple_double(4519 ...

  2. 【NX二次开发】Block UI 线条颜色/线型/宽度

    属性说明 常规         类型 描述     BlockID     String 控件ID     Enable     Logical 是否可操作     Group     Logical ...

  3. 【NX二次开发】获取两个面之间的所有面

    已知两个蓝色面,使用遍历面的方法求紫色面.算法例子: 1 bool is_NeighborFace(tag_t tagFace1, tag_t tagFace2) 2 { 3 vector<ta ...

  4. 【linux】驱动-12-并发与竞态

    目录 前言 12. 并发&竞态 12.1 并发&竞态概念 12.2 竞态解决方法 12.3 原子 12.3.1 原子介绍 12.3.2 原子操作步骤 12.3.3 原子 API 12. ...

  5. Windows的静态库与动态库

    Windows的静态库与动态库 1.静态库 1.1 静态库特点 运行不存在 静态库源码被链接到调用程序中 目标程序的归档 1.2 C语言静态库 C静态库的创建 创建一个静态库项目. 添加库程序,源文件 ...

  6. 【题解】Luogu p2986 [USACO10MAR]伟大的奶牛聚集Great Cow Gat 树型dp

    题目描述 Bessie is planning the annual Great Cow Gathering for cows all across the country and, of cours ...

  7. Mac为docker和kubectl添加自动命令补全

    我最新最全的文章都在南瓜慢说 www.pkslow.com,欢迎大家来喝茶! 1 前言 自动命令补全是非常有用的功能,特别是当命令有特别多参数时.显然,docker/kubectl就是这样的命令.我们 ...

  8. 详解 CDN 加速

    背景 本来是为了深入了解 CDN 的,结果发现前置知识:IP.域名.DNS 都还不算特别熟,所以先写了他们 现在终于来聊一聊 CDN 啦 本文素材均出自:https://www.bilibili.co ...

  9. VRRP简介以及配置案例

    一.背景 二.VRRP 概念介绍 三.实验操作 一.背景 局域网中的用户终端通常采用配置一个默认网关的形式访问外部网络,如果此时默认网关设备发生故障,将中断所有用户终端的网络访问,这很可能会给用户带来 ...

  10. hive学习笔记之六:HiveQL基础

    欢迎访问我的GitHub https://github.com/zq2599/blog_demos 内容:所有原创文章分类汇总及配套源码,涉及Java.Docker.Kubernetes.DevOPS ...