zoukankan      html  css  js  c++  java
  • 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
    View Code

    对于上面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

  • 相关阅读:
    JavaWeb的一些理解
    phpMysql安装遇到的两个问题
    正则表达式学习1
    《SOA思想、技术与系统集成应用详解》读书笔记四《SOA核心技术及应用》Apache Tuscany sca安装及与eclipse结合
    19本书,选5本,任两本不邻粗解
    J2ME中处理日期相关问题
    《JSP2.0 技术手册》读书笔记二HttpSession
    《SOA思想、技术与系统集成应用详解》读书笔记三SCA
    《SOA思想、技术与系统集成应用详解》读书笔记一
    《SOA思想、技术与系统集成应用详解》读书笔记二Java Web服务
  • 原文地址:https://www.cnblogs.com/smart-zihan/p/12100999.html
Copyright © 2011-2022 走看看