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

现在学习的是怎么写一个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. 【NX二次开发】Block UI RGB颜色选择器

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

  2. What is maven?

    Introduction Maven, a Yiddish word meaning accumulator(累加器) of knowledge, began as an attempt to sim ...

  3. 【dog与lxy】8.25题解-land

    land 题目描述 dog终于有了一块领地,但是现在可怜的dog面临着lxy的入侵,于是他决定在自己的领地设置炮楼来保卫自己免受QJ.现在dog找到它可以在领地上设置炮楼的N个地点.但是留给dog的时 ...

  4. kubelet之volume manager源码分析

    kubernetes ceph-csi分析目录导航 基于tag v1.17.4 https://github.com/kubernetes/kubernetes/releases/tag/v1.17. ...

  5. excel VBA中Xldown和xlup用法

    1.Worksheets("Sheet1").Range("A1").End(xlDown).Select     '意思为自A1起,返回从上往下的最后一个非空 ...

  6. 单片机项目中使用新IC芯片的调试方法

    前两天,一位小伙伴咨询我一款新IC芯片怎么使用,借此机会我顺便把我日常工作中经常用到的一种调试方法介绍给小伙伴们,希望对对大家有所帮助.准备仓促,文中难免有技术性错误,欢迎大家给予指正,并给出好的建议 ...

  7. AcWing 1273. 天才的记忆

    从前有个人名叫 WNB,他有着天才般的记忆力,他珍藏了许多许多的宝藏. 在他离世之后留给后人一个难题(专门考验记忆力的啊!),如果谁能轻松回答出这个问题,便可以继承他的宝藏. 题目是这样的:给你一大串 ...

  8. kotlin gradle 生成jni头文件

    目录 问题 解决方法 使用方法 代码 gradle task位置截图 问题 最近在用kotlin写jni,但是生成头文件的时候遇到了些问题. 首先 javah 在java >= 1.9 就被取消 ...

  9. linux 中获取进程和kill进程的几种方法

    ps: ps命令是最基本同时也是非常强大的进程查看命令,使用该命令可以确定有哪些进程正在运行和运行的状态.进程是否结束.进程有没有僵尸.哪些进程占用了过多的资源等等. 注意:ps是显示瞬间进程的状态, ...

  10. Java初级面试题整理

    先看再点赞,给自己一点思考的时间,如果对自己有帮助,微信搜索[程序职场]关注这个执着的职场程序员. 我有什么:职场规划指导,技能提升方法,讲不完的职场故事,个人成长经验. 1. Java语言有哪些特点 ...