2 a couple of classes for implementing partial tabbed-page like behaviour
9 a 'page tab' like framed button
11 def __init__(self
,parent
):
12 Frame
.__init
__(self
, parent
,borderwidth
=2,relief
=RIDGE
)
13 self
.button
=Radiobutton(self
,padx
=5,pady
=5,takefocus
=FALSE
,
14 underline
=0,indicatoron
=FALSE
,highlightthickness
=0,
15 borderwidth
=0,selectcolor
=self
.cget('bg'))
18 class TabPageSet(Frame
):
20 a set of 'pages' with TabButtons for controlling their display
22 def __init__(self
,parent
,pageNames
,**kw
):
24 pageNames - a list of strings, each string will be the dictionary key
25 to a page's data, and the name displayed on the page's tab. Should be
26 specified in desired page order. The first page will be the default
27 and first active page.
29 Frame
.__init
__(self
, parent
, kw
)
30 self
.grid_location(0,0)
31 self
.columnconfigure(0,weight
=1)
32 self
.rowconfigure(1,weight
=1)
33 self
.tabBar
=Frame(self
)
34 self
.tabBar
.grid(row
=0,column
=0,sticky
=EW
)
35 self
.activePage
=StringVar(self
)
38 for name
in pageNames
:
41 def ChangePage(self
,pageName
=None):
43 if pageName
in self
.pages
.keys():
44 self
.activePage
.set(pageName
)
46 raise 'Invalid TabPage Name'
47 ## pop up the active 'tab' only
48 for page
in self
.pages
.keys():
49 self
.pages
[page
]['tab'].config(relief
=RIDGE
)
50 self
.pages
[self
.GetActivePage()]['tab'].config(relief
=RAISED
)
52 self
.pages
[self
.GetActivePage()]['page'].lift()
54 def GetActivePage(self
):
55 return self
.activePage
.get()
57 def AddPage(self
,pageName
):
58 if pageName
in self
.pages
.keys():
59 raise 'TabPage Name Already Exists'
60 self
.pages
[pageName
]={'tab':PageTab(self
.tabBar
),
61 'page':Frame(self
,borderwidth
=2,relief
=RAISED
)}
62 self
.pages
[pageName
]['tab'].button
.config(text
=pageName
,
63 command
=self
.ChangePage
,variable
=self
.activePage
,
65 self
.pages
[pageName
]['tab'].pack(side
=LEFT
)
66 self
.pages
[pageName
]['page'].grid(row
=1,column
=0,sticky
=NSEW
)
67 if len(self
.pages
)==1: # adding first page
68 self
.defaultPage
=pageName
69 self
.activePage
.set(self
.defaultPage
)
72 def RemovePage(self
,pageName
):
73 if not pageName
in self
.pages
.keys():
74 raise 'Invalid TabPage Name'
75 self
.pages
[pageName
]['tab'].pack_forget()
76 self
.pages
[pageName
]['page'].grid_forget()
77 self
.pages
[pageName
]['tab'].destroy()
78 self
.pages
[pageName
]['page'].destroy()
79 del(self
.pages
[pageName
])
80 # handle removing last remaining, or default, or active page
81 if not self
.pages
: # removed last remaining page
84 if pageName
==self
.defaultPage
: # set a new default page
86 self
.tabBar
.winfo_children()[0].button
.cget('text')
87 if pageName
==self
.GetActivePage(): # set a new active page
88 self
.activePage
.set(self
.defaultPage
)
91 if __name__
== '__main__':
94 tabPage
=TabPageSet(root
,pageNames
=['Foobar','Baz'])
95 tabPage
.pack(expand
=TRUE
,fill
=BOTH
)
96 Label(tabPage
.pages
['Foobar']['page'],text
='Foo',pady
=20).pack()
97 Label(tabPage
.pages
['Foobar']['page'],text
='Bar',pady
=20).pack()
98 Label(tabPage
.pages
['Baz']['page'],text
='Baz').pack()
99 entryPgName
=Entry(root
)
100 buttonAdd
=Button(root
,text
='Add Page',
101 command
=lambda:tabPage
.AddPage(entryPgName
.get()))
102 buttonRemove
=Button(root
,text
='Remove Page',
103 command
=lambda:tabPage
.RemovePage(entryPgName
.get()))
104 labelPgName
=Label(root
,text
='name of page to add/remove:')
105 buttonAdd
.pack(padx
=5,pady
=5)
106 buttonRemove
.pack(padx
=5,pady
=5)
107 labelPgName
.pack(padx
=5)
108 entryPgName
.pack(padx
=5)