blob: 5b65601ce5cd3c743ae7f50a1d993d2ee15cf7b0 [file] [log] [blame]
Steven M. Gava5b357b92001-12-05 06:32:46 +00001"""
2a couple of classes for implementing partial tabbed-page like behaviour
3"""
4
5from Tkinter import *
6
Neal Norwitz5b0b00f2002-11-30 19:10:19 +00007class InvalidTabPage(Exception): pass
8class AlreadyExists(Exception): pass
9
Steven M. Gava5b357b92001-12-05 06:32:46 +000010class PageTab(Frame):
11 """
12 a 'page tab' like framed button
13 """
14 def __init__(self,parent):
15 Frame.__init__(self, parent,borderwidth=2,relief=RIDGE)
16 self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE,
Steven M. Gava361cfcd2002-01-03 12:02:37 +000017 indicatoron=FALSE,highlightthickness=0,
Steven M. Gava5b357b92001-12-05 06:32:46 +000018 borderwidth=0,selectcolor=self.cget('bg'))
19 self.button.pack()
20
21class TabPageSet(Frame):
22 """
23 a set of 'pages' with TabButtons for controlling their display
24 """
Steven M. Gava361cfcd2002-01-03 12:02:37 +000025 def __init__(self,parent,pageNames=[],**kw):
Steven M. Gava5b357b92001-12-05 06:32:46 +000026 """
27 pageNames - a list of strings, each string will be the dictionary key
28 to a page's data, and the name displayed on the page's tab. Should be
29 specified in desired page order. The first page will be the default
30 and first active page.
31 """
32 Frame.__init__(self, parent, kw)
33 self.grid_location(0,0)
34 self.columnconfigure(0,weight=1)
35 self.rowconfigure(1,weight=1)
36 self.tabBar=Frame(self)
37 self.tabBar.grid(row=0,column=0,sticky=EW)
38 self.activePage=StringVar(self)
39 self.defaultPage=''
40 self.pages={}
41 for name in pageNames:
42 self.AddPage(name)
43
44 def ChangePage(self,pageName=None):
45 if pageName:
46 if pageName in self.pages.keys():
47 self.activePage.set(pageName)
48 else:
Neal Norwitz5b0b00f2002-11-30 19:10:19 +000049 raise InvalidTabPage, 'Invalid TabPage Name'
Steven M. Gava5b357b92001-12-05 06:32:46 +000050 ## pop up the active 'tab' only
51 for page in self.pages.keys():
52 self.pages[page]['tab'].config(relief=RIDGE)
53 self.pages[self.GetActivePage()]['tab'].config(relief=RAISED)
54 ## switch page
55 self.pages[self.GetActivePage()]['page'].lift()
56
57 def GetActivePage(self):
58 return self.activePage.get()
59
60 def AddPage(self,pageName):
61 if pageName in self.pages.keys():
Neal Norwitz5b0b00f2002-11-30 19:10:19 +000062 raise AlreadyExists, 'TabPage Name Already Exists'
Steven M. Gava5b357b92001-12-05 06:32:46 +000063 self.pages[pageName]={'tab':PageTab(self.tabBar),
64 'page':Frame(self,borderwidth=2,relief=RAISED)}
65 self.pages[pageName]['tab'].button.config(text=pageName,
66 command=self.ChangePage,variable=self.activePage,
67 value=pageName)
68 self.pages[pageName]['tab'].pack(side=LEFT)
69 self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW)
70 if len(self.pages)==1: # adding first page
71 self.defaultPage=pageName
72 self.activePage.set(self.defaultPage)
73 self.ChangePage()
74
75 def RemovePage(self,pageName):
76 if not pageName in self.pages.keys():
Neal Norwitz5b0b00f2002-11-30 19:10:19 +000077 raise InvalidTabPage, 'Invalid TabPage Name'
Steven M. Gava5b357b92001-12-05 06:32:46 +000078 self.pages[pageName]['tab'].pack_forget()
79 self.pages[pageName]['page'].grid_forget()
80 self.pages[pageName]['tab'].destroy()
81 self.pages[pageName]['page'].destroy()
82 del(self.pages[pageName])
83 # handle removing last remaining, or default, or active page
84 if not self.pages: # removed last remaining page
85 self.defaultPage=''
86 return
87 if pageName==self.defaultPage: # set a new default page
88 self.defaultPage=\
89 self.tabBar.winfo_children()[0].button.cget('text')
90 if pageName==self.GetActivePage(): # set a new active page
91 self.activePage.set(self.defaultPage)
92 self.ChangePage()
93
94if __name__ == '__main__':
Steven M. Gava34b88512001-12-05 06:39:18 +000095 #test dialog
Steven M. Gava5b357b92001-12-05 06:32:46 +000096 root=Tk()
97 tabPage=TabPageSet(root,pageNames=['Foobar','Baz'])
98 tabPage.pack(expand=TRUE,fill=BOTH)
99 Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack()
100 Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack()
101 Label(tabPage.pages['Baz']['page'],text='Baz').pack()
102 entryPgName=Entry(root)
103 buttonAdd=Button(root,text='Add Page',
104 command=lambda:tabPage.AddPage(entryPgName.get()))
105 buttonRemove=Button(root,text='Remove Page',
106 command=lambda:tabPage.RemovePage(entryPgName.get()))
107 labelPgName=Label(root,text='name of page to add/remove:')
108 buttonAdd.pack(padx=5,pady=5)
109 buttonRemove.pack(padx=5,pady=5)
110 labelPgName.pack(padx=5)
111 entryPgName.pack(padx=5)
Steven M. Gava361cfcd2002-01-03 12:02:37 +0000112 tabPage.ChangePage()
Steven M. Gava5b357b92001-12-05 06:32:46 +0000113 root.mainloop()
114