用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() # 进入消息循环
下面是运行结果。