0001 """ 0002 a couple of classes for implementing partial tabbed-page like behaviour 0003 """ 0004 0005 from Tkinter import * 0006 0007 class InvalidTabPage(Exception): pass 0008 class AlreadyExists(Exception): pass 0009 0010 class PageTab(Frame): 0011 """ 0012 a 'page tab' like framed button 0013 """ 0014 def __init__(self,parent): 0015 Frame.__init__(self, parent,borderwidth=2,relief=RIDGE) 0016 self.button=Radiobutton(self,padx=5,pady=5,takefocus=FALSE, 0017 indicatoron=FALSE,highlightthickness=0, 0018 borderwidth=0,selectcolor=self.cget('bg')) 0019 self.button.pack() 0020 0021 class TabPageSet(Frame): 0022 """ 0023 a set of 'pages' with TabButtons for controlling their display 0024 """ 0025 def __init__(self,parent,pageNames=[],**kw): 0026 """ 0027 pageNames - a list of strings, each string will be the dictionary key 0028 to a page's data, and the name displayed on the page's tab. Should be 0029 specified in desired page order. The first page will be the default 0030 and first active page. 0031 """ 0032 Frame.__init__(self, parent, kw) 0033 self.grid_location(0,0) 0034 self.columnconfigure(0,weight=1) 0035 self.rowconfigure(1,weight=1) 0036 self.tabBar=Frame(self) 0037 self.tabBar.grid(row=0,column=0,sticky=EW) 0038 self.activePage=StringVar(self) 0039 self.defaultPage='' 0040 self.pages={} 0041 for name in pageNames: 0042 self.AddPage(name) 0043 0044 def ChangePage(self,pageName=None): 0045 if pageName: 0046 if pageName in self.pages.keys(): 0047 self.activePage.set(pageName) 0048 else: 0049 raise InvalidTabPage, 'Invalid TabPage Name' 0050 ## pop up the active 'tab' only 0051 for page in self.pages.keys(): 0052 self.pages[page]['tab'].config(relief=RIDGE) 0053 self.pages[self.GetActivePage()]['tab'].config(relief=RAISED) 0054 ## switch page 0055 self.pages[self.GetActivePage()]['page'].lift() 0056 0057 def GetActivePage(self): 0058 return self.activePage.get() 0059 0060 def AddPage(self,pageName): 0061 if pageName in self.pages.keys(): 0062 raise AlreadyExists, 'TabPage Name Already Exists' 0063 self.pages[pageName]={'tab':PageTab(self.tabBar), 0064 'page':Frame(self,borderwidth=2,relief=RAISED)} 0065 self.pages[pageName]['tab'].button.config(text=pageName, 0066 command=self.ChangePage,variable=self.activePage, 0067 value=pageName) 0068 self.pages[pageName]['tab'].pack(side=LEFT) 0069 self.pages[pageName]['page'].grid(row=1,column=0,sticky=NSEW) 0070 if len(self.pages)==1: # adding first page 0071 self.defaultPage=pageName 0072 self.activePage.set(self.defaultPage) 0073 self.ChangePage() 0074 0075 def RemovePage(self,pageName): 0076 if not pageName in self.pages.keys(): 0077 raise InvalidTabPage, 'Invalid TabPage Name' 0078 self.pages[pageName]['tab'].pack_forget() 0079 self.pages[pageName]['page'].grid_forget() 0080 self.pages[pageName]['tab'].destroy() 0081 self.pages[pageName]['page'].destroy() 0082 del(self.pages[pageName]) 0083 # handle removing last remaining, or default, or active page 0084 if not self.pages: # removed last remaining page 0085 self.defaultPage='' 0086 return 0087 if pageName==self.defaultPage: # set a new default page 0088 self.defaultPage=\ 0089 self.tabBar.winfo_children()[0].button.cget('text') 0090 if pageName==self.GetActivePage(): # set a new active page 0091 self.activePage.set(self.defaultPage) 0092 self.ChangePage() 0093 0094 if __name__ == '__main__': 0095 #test dialog 0096 root=Tk() 0097 tabPage=TabPageSet(root,pageNames=['Foobar','Baz']) 0098 tabPage.pack(expand=TRUE,fill=BOTH) 0099 Label(tabPage.pages['Foobar']['page'],text='Foo',pady=20).pack() 0100 Label(tabPage.pages['Foobar']['page'],text='Bar',pady=20).pack() 0101 Label(tabPage.pages['Baz']['page'],text='Baz').pack() 0102 entryPgName=Entry(root) 0103 buttonAdd=Button(root,text='Add Page', 0104 command=lambda:tabPage.AddPage(entryPgName.get())) 0105 buttonRemove=Button(root,text='Remove Page', 0106 command=lambda:tabPage.RemovePage(entryPgName.get())) 0107 labelPgName=Label(root,text='name of page to add/remove:') 0108 buttonAdd.pack(padx=5,pady=5) 0109 buttonRemove.pack(padx=5,pady=5) 0110 labelPgName.pack(padx=5) 0111 entryPgName.pack(padx=5) 0112 tabPage.ChangePage() 0113 root.mainloop() 0114
Generated by PyXR 0.9.4