| 1 | |
| 2 | from wxPython.wx import * |
| 3 | from wxPython.wizard import * |
| 4 | |
| 5 | import images |
| 6 | |
| 7 | #---------------------------------------------------------------------- |
| 8 | |
| 9 | def makePageTitle(wizPg, title): |
| 10 | sizer = wxBoxSizer(wxVERTICAL) |
| 11 | wizPg.SetSizer(sizer) |
| 12 | title = wxStaticText(wizPg, -1, title) |
| 13 | title.SetFont(wxFont(18, wxSWISS, wxNORMAL, wxBOLD)) |
| 14 | sizer.AddWindow(title, 0, wxALIGN_CENTRE|wxALL, 5) |
| 15 | sizer.AddWindow(wxStaticLine(wizPg, -1), 0, wxEXPAND|wxALL, 5) |
| 16 | return sizer |
| 17 | |
| 18 | #---------------------------------------------------------------------- |
| 19 | |
| 20 | class TitledPage(wxWizardPageSimple): |
| 21 | def __init__(self, parent, title): |
| 22 | wxWizardPageSimple.__init__(self, parent) |
| 23 | self.sizer = makePageTitle(self, title) |
| 24 | |
| 25 | |
| 26 | #---------------------------------------------------------------------- |
| 27 | |
| 28 | class SkipNextPage(wxPyWizardPage): |
| 29 | def __init__(self, parent, title): |
| 30 | wxPyWizardPage.__init__(self, parent) |
| 31 | self.next = self.prev = None |
| 32 | self.sizer = makePageTitle(self, title) |
| 33 | |
| 34 | self.cb = wxCheckBox(self, -1, "Skip next page") |
| 35 | self.sizer.Add(self.cb, 0, wxALL, 5) |
| 36 | |
| 37 | def SetNext(self, next): |
| 38 | self.next = next |
| 39 | |
| 40 | def SetPrev(self, prev): |
| 41 | self.prev = prev |
| 42 | |
| 43 | |
| 44 | # Classes derived from wxPyWizardPanel must override |
| 45 | # GetNext and GetPrev, and may also override GetBitmap |
| 46 | # as well as all those methods overridable by |
| 47 | # wxPyWindow. |
| 48 | |
| 49 | def GetNext(self): |
| 50 | """If the checkbox is set then return the next page's next page""" |
| 51 | next = self.next |
| 52 | if self.cb.GetValue(): |
| 53 | next = next.GetNext() |
| 54 | return next |
| 55 | |
| 56 | def GetPrev(self): |
| 57 | return self.prev |
| 58 | |
| 59 | #---------------------------------------------------------------------- |
| 60 | |
| 61 | class UseAltBitmapPage(wxPyWizardPage): |
| 62 | def __init__(self, parent, title): |
| 63 | wxPyWizardPage.__init__(self, parent) |
| 64 | self.next = self.prev = None |
| 65 | self.sizer = makePageTitle(self, title) |
| 66 | |
| 67 | self.sizer.Add(wxStaticText(self, -1, "This page uses a different bitmap"), |
| 68 | 0, wxALL, 5) |
| 69 | |
| 70 | def SetNext(self, next): |
| 71 | self.next = next |
| 72 | |
| 73 | def SetPrev(self, prev): |
| 74 | self.prev = prev |
| 75 | |
| 76 | def GetNext(self): |
| 77 | return self.next |
| 78 | |
| 79 | def GetPrev(self): |
| 80 | return self.prev |
| 81 | |
| 82 | def GetBitmap(self): |
| 83 | # You usually wouldn't need to override this method |
| 84 | # since you can set a non-default bitmap in the |
| 85 | # wxWizardPageSimple constructor, but if you need to |
| 86 | # dynamically change the bitmap based on the |
| 87 | # contents of the wizard, or need to also change the |
| 88 | # next/prev order then it can be done by overriding |
| 89 | # GetBitmap. |
| 90 | return images.getWizTest2Bitmap() |
| 91 | |
| 92 | #---------------------------------------------------------------------- |
| 93 | |
| 94 | class TestPanel(wxPanel): |
| 95 | ID_wiz = wxNewId() |
| 96 | |
| 97 | def __init__(self, parent, log): |
| 98 | self.log = log |
| 99 | wxPanel.__init__(self, parent, -1) |
| 100 | |
| 101 | b = wxButton(self, -1, "Run Simple Wizard", pos=(50, 50)) |
| 102 | EVT_BUTTON(self, b.GetId(), self.OnRunSimpleWizard) |
| 103 | |
| 104 | b = wxButton(self, -1, "Run Dynamic Wizard", pos=(50, 100)) |
| 105 | EVT_BUTTON(self, b.GetId(), self.OnRunDynamicWizard) |
| 106 | |
| 107 | EVT_WIZARD_PAGE_CHANGED(self, self.ID_wiz, self.OnWizPageChanged) |
| 108 | EVT_WIZARD_PAGE_CHANGING(self, self.ID_wiz, self.OnWizPageChanging) |
| 109 | EVT_WIZARD_CANCEL(self, self.ID_wiz, self.OnWizCancel) |
| 110 | |
| 111 | |
| 112 | def OnWizPageChanged(self, evt): |
| 113 | if evt.GetDirection(): |
| 114 | dir = "forward" |
| 115 | else: |
| 116 | dir = "backward" |
| 117 | page = evt.GetPage() |
| 118 | self.log.write("OnWizPageChanged: %s, %s\n" % (dir, page.__class__)) |
| 119 | |
| 120 | |
| 121 | def OnWizPageChanging(self, evt): |
| 122 | if evt.GetDirection(): |
| 123 | dir = "forward" |
| 124 | else: |
| 125 | dir = "backward" |
| 126 | page = evt.GetPage() |
| 127 | self.log.write("OnWizPageChanging: %s, %s\n" % (dir, page.__class__)) |
| 128 | |
| 129 | |
| 130 | def OnWizCancel(self, evt): |
| 131 | page = evt.GetPage() |
| 132 | self.log.write("OnWizCancel: %s\n" % page.__class__) |
| 133 | |
| 134 | # Show how to prevent cancelling of the wizard. The |
| 135 | # other events can be Veto'd too. |
| 136 | if page is self.page1: |
| 137 | wxMessageBox("Cancelling on the first page has been prevented.", "Sorry") |
| 138 | evt.Veto() |
| 139 | |
| 140 | |
| 141 | def OnRunSimpleWizard(self, evt): |
| 142 | # Create the wizard and the pages |
| 143 | wizard = wxWizard(self, self.ID_wiz, "Simple Wizard", |
| 144 | images.getWizTest1Bitmap()) |
| 145 | page1 = TitledPage(wizard, "Page 1") |
| 146 | page2 = TitledPage(wizard, "Page 2") |
| 147 | page3 = TitledPage(wizard, "Page 3") |
| 148 | page4 = TitledPage(wizard, "Page 4") |
| 149 | self.page1 = page1 |
| 150 | |
| 151 | page1.sizer.Add(wxStaticText(page1, -1, """ |
| 152 | This wizard is totally useless, but is meant to show how to |
| 153 | chain simple wizard pages together in a non-dynamic manner. |
| 154 | IOW, the order of the pages never changes, and so the |
| 155 | wxWizardPageSimple class can easily be used for the pages.""")) |
| 156 | wizard.FitToPage(page1) |
| 157 | page4.sizer.Add(wxStaticText(page4, -1, "\nThis is the last page.")) |
| 158 | |
| 159 | # Use the convenience Chain function to connect the pages |
| 160 | wxWizardPageSimple_Chain(page1, page2) |
| 161 | wxWizardPageSimple_Chain(page2, page3) |
| 162 | wxWizardPageSimple_Chain(page3, page4) |
| 163 | |
| 164 | if wizard.RunWizard(page1): |
| 165 | wxMessageBox("Wizard completed successfully", "That's all folks!") |
| 166 | else: |
| 167 | wxMessageBox("Wizard was cancelled", "That's all folks!") |
| 168 | |
| 169 | |
| 170 | |
| 171 | def OnRunDynamicWizard(self, evt): |
| 172 | # Create the wizard and the pages |
| 173 | wizard = wxWizard(self, self.ID_wiz, "Simple Wizard", |
| 174 | images.getWizTest1Bitmap()) |
| 175 | |
| 176 | page1 = TitledPage(wizard, "Page 1") |
| 177 | page2 = SkipNextPage(wizard, "Page 2") |
| 178 | page3 = TitledPage(wizard, "Page 3") |
| 179 | page4 = UseAltBitmapPage(wizard, "Page 4") |
| 180 | page5 = TitledPage(wizard, "Page 5") |
| 181 | self.page1 = page1 |
| 182 | |
| 183 | page1.sizer.Add(wxStaticText(page1, -1, """ |
| 184 | This wizard shows the ability to choose at runtime the order |
| 185 | of the pages and also which bitmap is shown. |
| 186 | """)) |
| 187 | wizard.FitToPage(page1) |
| 188 | page5.sizer.Add(wxStaticText(page5, -1, "\nThis is the last page.")) |
| 189 | |
| 190 | # Set the initial order of the pages |
| 191 | page1.SetNext(page2) |
| 192 | page2.SetPrev(page1) |
| 193 | page2.SetNext(page3) |
| 194 | page3.SetPrev(page2) |
| 195 | page3.SetNext(page4) |
| 196 | page4.SetPrev(page3) |
| 197 | page4.SetNext(page5) |
| 198 | page5.SetPrev(page4) |
| 199 | |
| 200 | |
| 201 | if wizard.RunWizard(page1): |
| 202 | wxMessageBox("Wizard completed successfully", "That's all folks!") |
| 203 | else: |
| 204 | wxMessageBox("Wizard was cancelled", "That's all folks!") |
| 205 | |
| 206 | #---------------------------------------------------------------------- |
| 207 | |
| 208 | def runTest(frame, nb, log): |
| 209 | win = TestPanel(nb, log) |
| 210 | return win |
| 211 | |
| 212 | #---------------------------------------------------------------------- |
| 213 | |
| 214 | |
| 215 | |
| 216 | overview = """<html><body> |
| 217 | <h2><center>wxWizard</center></h2> |
| 218 | |
| 219 | wxWizard is the central class for implementing 'wizard-like' |
| 220 | dialogs. These dialogs are mostly familiar to Windows users and are |
| 221 | nothing else but a sequence of 'pages' each of them displayed inside a |
| 222 | dialog which has the buttons to pass to the next (and previous) pages. |
| 223 | <p> |
| 224 | The wizards are typically used to decompose a complex dialog into |
| 225 | several simple steps and are mainly useful to the novice users, hence |
| 226 | it is important to keep them as simple as possible. |
| 227 | |
| 228 | </body></html> |
| 229 | """ |
| 230 | |
| 231 | |
| 232 | |
| 233 | if __name__ == '__main__': |
| 234 | import sys,os |
| 235 | import run |
| 236 | run.main(['', os.path.basename(sys.argv[0])]) |
| 237 | |