Bootstrap

用Tkinter打造GUI开发工具(19)ttk.Notebook笔记本小部件

用Tkinter打造GUI开发工具(19)ttk.Notebook笔记本小部件
ttk.Notebook笔记本组件类似多页的Frame,通过点击顶部标签的选项卡选择不同容器。笔记本小部件的目的是提供一个区域,用户可以通过单击区域顶部的选项卡来选择内容页面,如下所示:
每次用户单击其中一个选项卡时,窗口小部件将显示 与该选项卡关联的子窗格。通常,每个窗格都是 Frame窗口小部件,但窗格可以是任何窗口小部件。
当前显示的子窗格的选项卡称为选定选项卡。
您将使用Notebook窗口小部件的.add()方法附加新选项卡及其相关内容。其他方法允许您删除或暂时隐藏选项卡。
每个选项卡都有自己的一组选项来控制其外观和行为。
要将Notebook窗口小部件创建为某个窗口小部件的子parent窗口,请使用以下构造函数:

w= ttk.Notebook(parent,option= value,...)

ttk.Notebook选项包括:
在这里插入图片描述
ttk.Notebook小部件上的方法包括所有ttk小部件共有的方法”中描述的所有方法,以及以下方法:

.add(child, **kw)

该child 参数是一个小部件,通常Frame,它包装一个子窗格中的内容。如果child不是Notebook窗口小部件的子窗格之一,child则添加为下一个可用选项卡,关键字参数kw定义新窗格的选项卡选项。这些选项在表51“ ttk.Notebook 小部件的选项卡选项”中定义。
如果child是当前隐藏的窗格,则该选项卡将重新显示在其以前的位置。

.enable_traversal()

一旦调用此方法,一些额外的键绑定将起作用:
Control-Tab将在当前选择的选项卡后选择选项卡。如果当前选择了最后一个选项卡,则选择将旋转回第一个选项卡。
Shift-Control-Tab执行相反操作:它移动到上一个选项卡,如果选择了第一个选项卡,则环绕到最后一个选项卡。
您可以配置直接选择选项卡的特定热键。要执行此操作,请使用text和underline选项卡选项为每个选项卡中的一个字符加下划线。然后,用户可以通过键入Alt-跳转到选项卡,x其中 x是该选项卡上带下划线的字符。
如果Notebook在同一个应用程序中有多个小部件,则除非创建每个子窗格小部件并将其Notebook窗口小部件作为父窗口小部件,否则这些功能将无法正常工作。

.forget(child)

此方法child从窗口小部件的选项卡集中永久删除指定的内容。

.hide(tabId)

标识的选项卡tabId暂时从中显示的可见选项卡集中删除Notebook。您可以通过.add() 再次调用该方法来恢复它。

.index(tabId)

对于给定的tabId,此方法返回相应选项卡的数字索引。有一个例外:如果参数是字符串"end",则该方法将返回选项卡的总数。

.insert(where, child,**kw)

此方法使用任何关键字参数将窗口小部件插入到child指定的位置 where,以描述新选项卡和窗格。有关关键字选项,请参阅表51“ ttk.Notebook 小部件的选项卡选项”。
该where 参数可以是任何的:
“end” 在所有现有选项卡之后放置新选项卡。
现有的子窗口小部件; 在这种情况下,new child就在现有小部件之前插入。

.select([tabId])

如果在没有参数的情况下调用此方法,它将返回当前显示其选项卡的窗口小部件的窗口名称。
要显示特定窗格Notebook,请使用a tabId作为参数调用此方法。

.tab(tabId, option=None, **kw)

使用此方法可以为所描述的子窗格设置选项卡选项tabId,或者找出为该子窗格设置的选项。
如果您调用没有关键字参数的方法,它将返回当前对指定的窗格有效的选项卡选项的字典tagId。
要查找特定选项卡选项的当前值 X,请使用参数“option=X” 调用此方法,该方法将返回该选项卡选项的值。
要为描述的子项设置一个或多个选项卡选项tagId,请使用关键字参数调用此方法。例如,如果self.nb 是 Notebook,则此调用将更改第一个选项卡上显示的文本:

self.nb.tab(0, text=‘Crunchy frog’)

.tabs()

此方法返回的列表窗口名称中的Notebook的子窗格中,从第一个到最后的次序。
以下是.add()和 .tab()方法中使用的选项卡选项。
ttk.Notebook 小部件的选项卡选项。

在这里插入图片描述
ttk.Notebook 小部件的虚拟事件。每当选定的选项卡在ttk.Notebook小部件中更改时,它都会生成“ <>”虚拟事件。
下面看一个ttk.Notebook 小部件的演示程序.

# -*- coding: utf-8 -*-
import tkinter as tk  #装载tkinter模块,用于Python3
from tkinter import ttk  #装载tkinter.ttk模块,用于Python3

root =tk.Tk()  # 创建窗口对象
root.title(string = 'ttk.Notebook演示')  #设置窗口标题
root.geometry('400x300+200+200')

tabControl = ttk.Notebook(root)  #创建Notebook
tab1 = tk.Frame(tabControl,bg='blue')  #增加新选项卡
tabControl.add(tab1, text='信息窗')  #把新选项卡增加到Notebook
tab2 = tk.Frame(tabControl,bg='yellow')
tabControl.add(tab2, text='综合信息')
tab3 = tk.Frame(tabControl,bg='green')
tabControl.add(tab3, text='技术分析')
tab4 = tk.Frame(tabControl,bg='blue')
tabControl.add(tab4, text='编写代码')
tab5 = tk.Frame(tabControl,bg='blue') 
tabControl.add(tab5, text='模拟回测')

tab6 = ttk.Frame(tabControl) 
tabControl.add(tab6, text='双色球')
tab7 = ttk.Frame(tabControl) 
tabControl.add(tab7, text='大乐透')
tabControl.pack(expand=1, fill="both")

tabControl.select(tab1) #选择tab1

root.mainloop()     # 进入消息循环

程序运行结果如下图。
在这里插入图片描述
上面程序我们混合使用了tk和ttk的Frame组件。
ttk.Notebook为我们的Tkinter增加了一个新的功能部件,但是这个部件的Tab名只能在左上角显示,我们无法把它移动到左下角。
因此我们对 ttk.Notebook不满意,可以自己设计一个Notebook2组件。
下面看我把我在HP_tk2中设计的Notebook2组件类展示给大家,大家可以参照此组件类设计更多的新组件。

 # -*- coding: utf-8 -*-
import tkinter as tk  #装载tkinter模块,用于Python3
from tkinter import ttk  #装载tkinter.ttk模块,用于Python3

#------------HP_tk2中Notebook2模块
class Notebook2(tk.Frame): # 继承Frame类的Notebook类
    def __init__(self, master=None,m=0,anchor=tk.NW, size=9,width=10,**kw):  
        tk.Frame.__init__(self, master,**kw)  
        self.root = master #定义内部变量root
        self.m=m
        self.width=width
        self.size=size
        self.anchor=anchor
        self.s1=tk.TOP
        self.s2=tk.BOTTOM
        if (self.anchor in [tk.SW,tk.S,tk.SE]):
            self.s1=tk.BOTTOM
            self.s2=tk.TOP
        self.t=[]
        self.v=[]
        self.view=None
        self.pack(side=self.s2, fill=tk.BOTH, expand=1,ipady=1,pady=1,ipadx=1,padx=1)

        self.tab()


    def add(self,tab=None,text=''):
        if (tab!=None):
            self.m=self.m+1
            def handler (self=self, i=self.m-1 ):
                self.select(i)
            
            if (self.anchor in [tk.NW,tk.N,tk.SW,tk.S]):
                self.button = tk.Button(self.tab, width=self.width,text=text, cursor='hand2',
                                        anchor=tk.S,
                                        font=('Helvetica', '%d'%self.size),
                                        command=handler)
                self.t.append(self.button)
                self.button.pack(side=tk.LEFT)
                self.v.append(tab)
                if (self.m==1):
                    self.select(0)


            if (self.anchor in [tk.NE,tk.SE]):
                self.button = tk.Button(self.tab, width=self.width,text=text, cursor='hand2',
                                        anchor=tk.S,
                                        font=('Helvetica','%d'%self.size),
                                        command=handler)
                self.t.append(self.button)
                self.button.pack(side=tk.RIGHT)
                self.v.append(tab)
                if (self.m==1):
                    self.select(0)


    def tab(self):
        self.tab=tk.Frame(self)
        if (self.anchor in [tk.N,tk.S]):
            self.tab.pack(side=self.s1)
        if (self.anchor in [tk.NW,tk.NE,tk.SW,tk.SE]):
            self.tab.pack(side=self.s1,fill=tk.X)

        
        for i in range(self.m):
            def handler (self=self, i=i ):
                self.select(i)
            self.button = tk.Button(self.tab, width=self.width,text='Tab%d'%i, cursor='hand2',
                                    anchor=tk.S,
                                    font=('Helvetica','%d'%self.size),
                                    command=handler)
            self.t.append(self.button)
            self.v.append(None)
            if (self.anchor in [tk.NW,tk.SW]) :
                self.button.pack(side=tk.LEFT)
            else:
                self.button.pack(side=tk.RIGHT)
            
        self.update()

         
    def frame(self):
        self.frame=tk.Frame(self,bd=2,
                            borderwidth=2,  #边框宽度
                            padx=1,  #部件x方向间距
                            pady=1, #部件y方向间距
                            )
        self.frame.pack(side=self.s2,fill=tk.BOTH, expand=1)         


    def select(self,x):
        print(x)
        if (self.view!=None):
            self.view.pack_forget()
        for i in range(self.m):
            self.t[i]['relief']=tk.RIDGE
            self.t[i]['anchor']=tk.S
            self.t[i]['bg']="#F0F0ED"
            
        self.t[x]['anchor']=tk.N
        self.t[x]['bg']='white'
        self.view=self.v[x]
        if (self.view!=None):
            self.view.pack(fill=tk.BOTH, expand=1)   


    def modify(self,x,tab=None,text=''):
        if (x>self.m-1):
            return
        if (tab!=None):
            self.v[x]=tab
        if (text!=''):
            self.t[x]['text']=text
#------上面是class Notebook2定义

root =tk.Tk()  # 创建窗口对象
root.title(string = 'ttk.Notebook演示')  #设置窗口标题
root.geometry('800x600+200+200')

tabControl = ttk.Notebook(root)  #创建Notebook
tab1 = tk.Frame(tabControl,bg='blue')  #增加新选项卡
tabControl.add(tab1, text='信息窗')  #把新选项卡增加到Notebook
tab2 = tk.Frame(tabControl,bg='yellow')
tabControl.add(tab2, text='综合信息')
tab3 = tk.Frame(tabControl,bg='green')
tabControl.add(tab3, text='技术分析')
tab4 = tk.Frame(tabControl,bg='blue')
tabControl.add(tab4, text='编写代码')
tab5 = tk.Frame(tabControl,bg='blue') 
tabControl.add(tab5, text='模拟回测')

tab6 = ttk.Frame(tabControl) 
tabControl.add(tab6, text='双色球')
tab7 = ttk.Frame(tabControl) 
tabControl.add(tab7, text='大乐透')
tabControl.pack(expand=1, fill="both")

tabControl.select(tab1) #选择tab1
#---------------演示1------------------------------------
mytabControl=Notebook2(tab1,anchor=tk.SW)
mytab1 = tk.Frame(mytabControl,bg='red')  #增加新选项卡
mytabControl.add(mytab1,text='信息1')
mytab2 = tk.Frame(mytabControl,bg='blue')  #增加新选项卡
mytabControl.add(mytab2,text='信息2')
mytab3 = tk.Frame(mytabControl,bg='yellow')  #增加新选项卡
mytabControl.add(mytab3,text='信息3')
#---------------演示2------------------------------------
mytabControl2=Notebook2(tab2,m=3)
mytabControl3=Notebook2(tab3,m=4,anchor=tk.SW)
mytabControl4=Notebook2(tab4,m=5,anchor=tk.S)
mytabControl5=Notebook2(tab5,m=4,anchor=tk.N)
mytabControl6=Notebook2(tab6,m=5,anchor=tk.SE)
mytabControl7=Notebook2(tab7,m=4,anchor=tk.NE)

root.mainloop()     # 进入消息循环

下面是运行结果。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

;