Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 1 | """ |
| 2 | a couple of classes for implementing partial tabbed-page like behaviour |
| 3 | """ |
| 4 | |
| 5 | from Tkinter import * |
| 6 | |
Neal Norwitz | 5b0b00f | 2002-11-30 19:10:19 +0000 | [diff] [blame] | 7 | class InvalidTabPage(Exception): pass |
| 8 | class AlreadyExists(Exception): pass |
| 9 | |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 10 | class PageTab(Frame): |
| 11 | """ |
| 12 | a 'page tab' like framed button |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 13 | """ |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 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. Gava | 361cfcd | 2002-01-03 12:02:37 +0000 | [diff] [blame] | 17 | indicatoron=FALSE,highlightthickness=0, |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 18 | borderwidth=0,selectcolor=self.cget('bg')) |
| 19 | self.button.pack() |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 20 | |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 21 | class TabPageSet(Frame): |
| 22 | """ |
| 23 | a set of 'pages' with TabButtons for controlling their display |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 24 | """ |
Steven M. Gava | 361cfcd | 2002-01-03 12:02:37 +0000 | [diff] [blame] | 25 | def __init__(self,parent,pageNames=[],**kw): |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 26 | """ |
| 27 | pageNames - a list of strings, each string will be the dictionary key |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 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 |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 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 Norwitz | 5b0b00f | 2002-11-30 19:10:19 +0000 | [diff] [blame] | 49 | raise InvalidTabPage, 'Invalid TabPage Name' |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 50 | ## pop up the active 'tab' only |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 51 | for page in self.pages.keys(): |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 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() |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 56 | |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 57 | def GetActivePage(self): |
| 58 | return self.activePage.get() |
| 59 | |
| 60 | def AddPage(self,pageName): |
| 61 | if pageName in self.pages.keys(): |
Neal Norwitz | 5b0b00f | 2002-11-30 19:10:19 +0000 | [diff] [blame] | 62 | raise AlreadyExists, 'TabPage Name Already Exists' |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 63 | 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) |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 70 | if len(self.pages)==1: # adding first page |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 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 Norwitz | 5b0b00f | 2002-11-30 19:10:19 +0000 | [diff] [blame] | 77 | raise InvalidTabPage, 'Invalid TabPage Name' |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 78 | 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='' |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 86 | return |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 87 | if pageName==self.defaultPage: # set a new default page |
| 88 | self.defaultPage=\ |
| 89 | self.tabBar.winfo_children()[0].button.cget('text') |
Kurt B. Kaiser | 6655e4b | 2002-12-31 16:03:23 +0000 | [diff] [blame] | 90 | if pageName==self.GetActivePage(): # set a new active page |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 91 | self.activePage.set(self.defaultPage) |
| 92 | self.ChangePage() |
| 93 | |
| 94 | if __name__ == '__main__': |
Steven M. Gava | 34b8851 | 2001-12-05 06:39:18 +0000 | [diff] [blame] | 95 | #test dialog |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 96 | 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. Gava | 361cfcd | 2002-01-03 12:02:37 +0000 | [diff] [blame] | 112 | tabPage.ChangePage() |
Steven M. Gava | 5b357b9 | 2001-12-05 06:32:46 +0000 | [diff] [blame] | 113 | root.mainloop() |