123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732 |
- """
- MODULE: r_li_setup_GUI.py
- AUTHOR(S): Anne Ghisla <a.ghisla AT gmail.com>
- PURPOSE: Dedicated GUI for r.li.setup, translated and reshaped from original TclTk.
- DEPENDS: []
- COPYRIGHT: (C) 2010 by the GRASS Development Team
- This program is free software under the GNU General Public
- License (>=v2). Read the file COPYING that comes with GRASS
- for details.
- """
- # bulk import from location_wizard.py.
- import os
- import shutil
- import re
- import string
- import sys
- import locale
- import platform
- GUIModulesPath = os.path.join(os.getenv("GISBASE"), "etc", "gui", "wxpython", "gui_modules")
- sys.path.append(GUIModulesPath)
- from core import globalvar
- import wx
- import wx.lib.mixins.listctrl as listmix
- import wx.wizard as wiz
- import wx.lib.scrolledpanel as scrolled
- import time
- from core import cmd as gcmd
- from core import utils
- from grass.script import core as grass
- #@TODO create wizard instead of progressively increasing window
- print >> sys.stderr, "TODO: implement r.li.setup wizard..."
- #@NOTE: r.li.setup writes in the settings file with
- ## r.li.windows.tcl:
- #exec echo "SAMPLINGFRAME $per_x|$per_y|$per_rl|$per_cl" >> $env(TMP).set
- class BaseClass(wx.Object):
- """!Base class providing basic methods"""
- def __init__(self):
- pass
- def MakeLabel(self, text="", style=wx.ALIGN_LEFT, parent=None):
- """!Make aligned label"""
- if not parent:
- parent = self
- return wx.StaticText(parent=parent, id=wx.ID_ANY, label=text,
- style=style)
- def MakeTextCtrl(self, text='', size=(100,-1), style=0, parent=None):
- """!Generic text control"""
- if not parent:
- parent = self
- return wx.TextCtrl(parent=parent, id=wx.ID_ANY, value=text,
- size=size, style=style)
- def MakeButton(self, text, id=wx.ID_ANY, size=(-1,-1), parent=None):
- """!Generic button"""
- if not parent:
- parent = self
- return wx.Button(parent=parent, id=id, label=text,
- size=size)
- class TitledPage(BaseClass, wiz.WizardPageSimple):
- """
- Class to make wizard pages. Generic methods to make
- labels, text entries, and buttons.
- """
- def __init__(self, parent, title):
- self.page = wiz.WizardPageSimple.__init__(self, parent)
- # page title
- self.title = wx.StaticText(parent=self, id=wx.ID_ANY, label=title)
- self.title.SetFont(wx.Font(13, wx.SWISS, wx.NORMAL, wx.BOLD))
- # main sizers
- self.pagesizer = wx.BoxSizer(wx.VERTICAL)
- self.sizer = wx.GridBagSizer(vgap=0, hgap=0)
-
- def DoLayout(self):
- """!Do page layout"""
-
- self.pagesizer.Add(item=self.title, proportion=0,
- flag=wx.ALIGN_CENTRE | wx.ALL,
- border=5)
- self.pagesizer.Add(item=wx.StaticLine(self, -1), proportion=0,
- flag=wx.EXPAND | wx.ALL,
- border=0)
- self.pagesizer.Add(item=self.sizer)
- self.SetAutoLayout(True)
- self.SetSizer(self.pagesizer)
- # tmpsizer.Fit(self)
- self.Layout()
-
-
- class LocationWizard(wx.Object):
- """
- Start wizard here and finish wizard here
- """
- def __init__(self, parent):
- # global coordsys
- self.parent = parent
- #
- # define wizard image
- #
- # file = "loc_wizard.png"
- file = "loc_wizard_qgis.png"
- imagePath = os.path.join(globalvar.ETCIMGDIR, file)
- wizbmp = wx.Image(imagePath, wx.BITMAP_TYPE_PNG)
- # wizbmp.Rescale(250,600)
- wizbmp = wizbmp.ConvertToBitmap()
- #
- # get georeferencing information from tables in $GISBASE/etc
- #
- # self.__readData()
- #
- # #
- # # datum transform number and list of datum transforms
- # #
- # self.datumtrans = 0
- # self.proj4string = ''
- #
- # #
- # # define wizard pages
- # #
- self.wizard = wiz.Wizard(parent, id=wx.ID_ANY, title=_("I m!"),
- bitmap=wizbmp)
- self.startpage = SummaryPage(self.wizard, self)
- # self.csystemspage = CoordinateSystemPage(self.wizard, self)
- # self.projpage = ProjectionsPage(self.wizard, self)
- # self.datumpage = DatumPage(self.wizard, self)
- # self.paramspage = ProjParamsPage(self.wizard,self)
- # self.epsgpage = EPSGPage(self.wizard, self)
- # self.filepage = GeoreferencedFilePage(self.wizard, self)
- # self.wktpage = WKTPage(self.wizard, self)
- # self.ellipsepage = EllipsePage(self.wizard, self)
- # self.custompage = CustomPage(self.wizard, self)
- # self.sumpage = SummaryPage(self.wizard, self)
- #
- # #
- # # set the initial order of the pages
- # # (should follow the epsg line)
- # #
- # self.startpage.SetNext(self.csystemspage)
- #
- # self.csystemspage.SetPrev(self.startpage)
- # self.csystemspage.SetNext(self.sumpage)
- #
- # self.projpage.SetPrev(self.csystemspage)
- # self.projpage.SetNext(self.paramspage)
- #
- # self.paramspage.SetPrev(self.projpage)
- # self.paramspage.SetNext(self.datumpage)
- #
- # self.datumpage.SetPrev(self.paramspage)
- # self.datumpage.SetNext(self.sumpage)
- #
- # self.ellipsepage.SetPrev(self.paramspage)
- # self.ellipsepage.SetNext(self.sumpage)
- #
- # self.epsgpage.SetPrev(self.csystemspage)
- # self.epsgpage.SetNext(self.sumpage)
- #
- # self.filepage.SetPrev(self.csystemspage)
- # self.filepage.SetNext(self.sumpage)
- #
- # self.wktpage.SetPrev(self.csystemspage)
- # self.wktpage.SetNext(self.sumpage)
- #
- # self.custompage.SetPrev(self.csystemspage)
- # self.custompage.SetNext(self.sumpage)
- #
- # self.sumpage.SetPrev(self.csystemspage)
- #
- # #
- # # do pages layout
- # #
- # self.startpage.DoLayout()
- # self.csystemspage.DoLayout()
- # self.projpage.DoLayout()
- # self.datumpage.DoLayout()
- # self.paramspage.DoLayout()
- # self.epsgpage.DoLayout()
- # self.filepage.DoLayout()
- # self.wktpage.DoLayout()
- # self.ellipsepage.DoLayout()
- # self.custompage.DoLayout()
- # self.sumpage.DoLayout()
- # self.wizard.FitToPage(self.datumpage)
- #
- # # new location created?
- # self.location = None
- # success = False
- #
- # # location created in different GIS database?
- # self.altdb = False
- #
- # run wizard...
- #
- if self.wizard.RunWizard(self.startpage):
- pass
- # msg = self.OnWizFinished()
- # if len(msg) < 1:
- # self.wizard.Destroy()
- # self.location = self.startpage.location
- #
- # if self.altdb == False:
- # dlg = wx.MessageDialog(parent=self.parent,
- # message=_("Do you want to set the default "
- # "region extents and resolution now?"),
- # caption=_("Location <%s> created") % self.location,
- # style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
- # dlg.CenterOnScreen()
- # if dlg.ShowModal() == wx.ID_YES:
- # dlg.Destroy()
- # defineRegion = RegionDef(self.parent, location=self.location)
- # defineRegion.CenterOnScreen()
- # defineRegion.Show()
- # else:
- # dlg.Destroy()
- # else: # -> error
- # self.wizard.Destroy()
- # wx.MessageBox(parent=self.parent,
- # message="%s" % _("Unable to create new location. "
- # "Location <%(loc)s> not created.\n\n"
- # "Details: %(err)s") % \
- # { 'loc' : self.startpage.location,
- # 'err' : msg },
- # caption=_("Location wizard"),
- # style=wx.OK | wx.ICON_ERROR | wx.CENTRE)
- # else:
- # win = wx.MessageBox(parent=self.parent,
- # message=_("Location wizard canceled. "
- # "Location not created."),
- # caption=_("Location wizard"))
-
- def __readData(self):
- """!Get georeferencing information from tables in $GISBASE/etc"""
- # read projection and parameters
- f = open(os.path.join(globalvar.ETCDIR, "proj-parms.table"), "r")
- self.projections = {}
- self.projdesc = {}
- for line in f.readlines():
- line = line.strip()
- try:
- proj, projdesc, params = line.split(':')
- paramslist = params.split(';')
- plist = []
- for p in paramslist:
- if p == '': continue
- p1, pdefault = p.split(',')
- pterm, pask = p1.split('=')
- p = [pterm.strip(), pask.strip(), pdefault.strip()]
- plist.append(p)
- self.projections[proj.lower().strip()] = (projdesc.strip(), plist)
- self.projdesc[proj.lower().strip()] = projdesc.strip()
- except:
- continue
- f.close()
- # read datum definitions
- f = open(os.path.join(globalvar.ETCDIR, "datum.table"), "r")
- self.datums = {}
- paramslist = []
- for line in f.readlines():
- line = line.expandtabs(1)
- line = line.strip()
- if line == '' or line[0] == "#":
- continue
- datum, info = line.split(" ", 1)
- info = info.strip()
- datumdesc, params = info.split(" ", 1)
- datumdesc = datumdesc.strip('"')
- paramlist = params.split()
- ellipsoid = paramlist.pop(0)
- self.datums[datum] = (ellipsoid, datumdesc.replace('_', ' '), paramlist)
- f.close()
- # read ellipsiod definitions
- f = open(os.path.join(globalvar.ETCDIR, "ellipse.table"), "r")
- self.ellipsoids = {}
- for line in f.readlines():
- line = line.expandtabs(1)
- line = line.strip()
- if line == '' or line[0] == "#":
- continue
- ellipse, rest = line.split(" ", 1)
- rest = rest.strip('" ')
- desc, params = rest.split('"', 1)
- desc = desc.strip('" ')
- paramslist = params.split()
- self.ellipsoids[ellipse] = (desc, paramslist)
- f.close()
-
- # read projection parameter description and parsing table
- f = open(os.path.join(globalvar.ETCDIR, "proj-desc.table"), "r")
- self.paramdesc = {}
- for line in f.readlines():
- line = line.strip()
- try:
- pparam, datatype, proj4term, desc = line.split(':')
- self.paramdesc[pparam] = (datatype, proj4term, desc)
- except:
- continue
- f.close()
- def OnWizFinished(self):
- database = self.startpage.grassdatabase
- location = self.startpage.location
- global coordsys
- msg = '' # error message (empty on success)
-
- # location already exists?
- if os.path.isdir(os.path.join(database,location)):
- dlg = wx.MessageDialog(parent=self.wizard,
- message="%s <%s>: %s" % \
- (_("Unable to create new location"),
- os.path.join(database, location),
- _("Location already exists in GRASS Database.")),
- caption=_("Error"),
- style=wx.OK | wx.ICON_ERROR)
- dlg.ShowModal()
- dlg.Destroy()
- return False
-
- # current GISDbase or a new one?
- current_gdb = grass.gisenv()['GISDBASE']
- if current_gdb != database:
- # change to new GISDbase or create new one
- if os.path.isdir(database) != True:
- # create new directory
- os.mkdir(database)
-
- # change to new GISDbase directory
- gcmd.RunCommand('g.gisenv',
- parent = self.wizard,
- set='GISDBASE=%s' % database)
-
- wx.MessageBox(parent=self.wizard,
- message=_("Location <%(loc)s> will be created "
- "in GIS data directory <%(dir)s>."
- "You will need to change the default GIS "
- "data directory in the GRASS startup screen.") % \
- { 'loc' : location, 'dir' : database},
- caption=_("New GIS data directory"),
- style=wx.OK | wx.ICON_INFORMATION | wx.CENTRE)
- # location created in alternate GISDbase
- self.altdb = True
-
- if coordsys == "xy":
- msg = self.XYCreate()
- elif coordsys == "proj":
- proj4string = self.CreateProj4String()
- msg = self.Proj4Create(proj4string)
- elif coordsys == 'custom':
- msg = self.CustomCreate()
- elif coordsys == "epsg":
- msg = self.EPSGCreate()
- elif coordsys == "file":
- msg = self.FileCreate()
- elif coordsys == "wkt":
- msg = self.WKTCreate()
- return msg
- def XYCreate(self):
- """!Create an XY location
- @return error message (empty string on success)
- """
- database = self.startpage.grassdatabase
- location = self.startpage.location
-
- # create location directory and PERMANENT mapset
- try:
- os.mkdir(os.path.join(database, location))
- os.mkdir(os.path.join(database, location, 'PERMANENT'))
- # create DEFAULT_WIND and WIND files
- regioninfo = ['proj: 0',
- 'zone: 0',
- 'north: 1',
- 'south: 0',
- 'east: 1',
- 'west: 0',
- 'cols: 1',
- 'rows: 1',
- 'e-w resol: 1',
- 'n-s resol: 1',
- 'top: 1',
- 'bottom: 0',
- 'cols3: 1',
- 'rows3: 1',
- 'depths: 1',
- 'e-w resol3: 1',
- 'n-s resol3: 1',
- 't-b resol: 1']
-
- defwind = open(os.path.join(database, location,
- "PERMANENT", "DEFAULT_WIND"), 'w')
- for param in regioninfo:
- defwind.write(param + '%s' % os.linesep)
- defwind.close()
-
- shutil.copy(os.path.join(database, location, "PERMANENT", "DEFAULT_WIND"),
- os.path.join(database, location, "PERMANENT", "WIND"))
-
- # create MYNAME file
- myname = open(os.path.join(database, location, "PERMANENT",
- "MYNAME"), 'w')
- myname.write('%s' % os.linesep)
- myname.close()
- except OSError, e:
- return e
-
- return ''
- def CreateProj4String(self):
- """!Constract PROJ.4 string"""
- location = self.startpage.location
- proj = self.projpage.p4proj
- projdesc = self.projpage.projdesc
- proj4params = self.paramspage.p4projparams
-
- datum = self.datumpage.datum
- if self.datumpage.datumdesc:
- datumdesc = self.datumpage.datumdesc +' - ' + self.datumpage.ellipse
- else:
- datumdesc = ''
- datumparams = self.datumpage.datumparams
- ellipse = self.ellipsepage.ellipse
- ellipsedesc = self.ellipsepage.ellipsedesc
- ellipseparams = self.ellipsepage.ellipseparams
-
- #
- # creating PROJ.4 string
- #
- proj4string = '%s %s' % (proj, proj4params)
-
- # set ellipsoid parameters
- if ellipse != '': proj4string = '%s +ellps=%s' % (proj4string, ellipse)
- for item in ellipseparams:
- if item[:4] == 'f=1/':
- item = ' +rf='+item[4:]
- else:
- item = ' +'+item
- proj4string = '%s %s' % (proj4string, item)
-
- # set datum and transform parameters if relevant
- if datum != '': proj4string = '%s +datum=%s' % (proj4string, datum)
- if datumparams:
- for item in datumparams:
- proj4string = '%s +%s' % (proj4string,item)
- proj4string = '%s +no_defs' % proj4string
-
- return proj4string
-
- def Proj4Create(self, proj4string):
- """!Create a new location for selected projection
-
- @return error message (empty string on success)
- """
- ret, msg = gcmd.RunCommand('g.proj',
- flags = 'c',
- proj4 = proj4string,
- location = self.startpage.location,
- datumtrans = self.datumtrans,
- getErrorMsg = True)
-
- if ret == 0:
- return ''
- return msg
-
- def CustomCreate(self):
- """!Create a new location based on given proj4 string
- @return error message (empty string on success)
- """
- proj4string = self.custompage.customstring
- location = self.startpage.location
-
- ret, msg = gcmd.RunCommand('g.proj',
- flags = 'c',
- proj4 = proj4string,
- location = location,
- getErrorMsg = True)
-
- if ret == 0:
- return ''
-
- return msg
- def EPSGCreate(self):
- """!Create a new location from an EPSG code.
- @return error message (empty string on success)
- """
- epsgcode = self.epsgpage.epsgcode
- epsgdesc = self.epsgpage.epsgdesc
- location = self.startpage.location
-
- # should not happend
- if epsgcode == '':
- return _('EPSG code missing.')
-
- ret, msg = gcmd.RunCommand('g.proj',
- flags = 'c',
- epsg = epsgcode,
- location = location,
- datumtrans = self.datumtrans,
- getErrorMsg = True)
-
- if ret == 0:
- return ''
- return msg
- def FileCreate(self):
- """!Create a new location from a georeferenced file
- @return error message (empty string on success)
- """
- georeffile = self.filepage.georeffile
- location = self.startpage.location
-
- # this should not happen
- if not georeffile or not os.path.isfile(georeffile):
- return _("File not found.")
-
- # creating location
- ret, msg = gcmd.RunCommand('g.proj',
- flags = 'c',
- georef = georeffile,
- location = location,
- getErrorMsg = True)
-
- if ret == 0:
- return ''
-
- return msg
- def WKTCreate(self):
- """!Create a new location from a WKT file
-
- @return error message (empty string on success)
- """
- wktfile = self.wktpage.wktfile
- location = self.startpage.location
-
- # this should not happen
- if not wktfile or not os.path.isfile(wktfile):
- return _("File not found.")
-
- # creating location
- ret, msg = gcmd.RunCommand('g.proj',
- flags = 'c',
- wkt = wktfile,
- location = location,
- getErrorMsg = True)
-
- if ret == 0:
- return ''
-
- return msg
-
- class SummaryPage(TitledPage):
- """
- Shows summary result of choosing coordinate system parameters
- prior to creating location
- """
- def __init__(self, wizard, parent):
- TitledPage.__init__(self, wizard, _("Summary"))
- self.parent = parent
- # labels
- self.ldatabase = self.MakeLabel("")
- self.llocation = self.MakeLabel("")
- self.lprojection = self.MakeLabel("")
- self.lproj4string = self.MakeLabel("")
- self.lproj4stringLabel = self.MakeLabel("")
-
- self.lprojection.Wrap(400)
-
- self.Bind(wiz.EVT_WIZARD_PAGE_CHANGED, self.OnEnterPage)
- # self.Bind(wx.EVT_BUTTON, self.OnFinish, wx.ID_FINISH)
- # do sub-page layout
- self.__DoLayout()
-
- def __DoLayout(self):
- """!Do page layout"""
- self.sizer.AddGrowableCol(1)
- self.sizer.Add(item=self.MakeLabel(_("GRASS Database:")),
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(1, 0))
- self.sizer.Add(item=self.ldatabase,
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(1, 1))
- self.sizer.Add(item=self.MakeLabel(_("Location Name:")),
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(2, 0))
- self.sizer.Add(item=self.llocation,
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(2, 1))
- self.sizer.Add(item=self.MakeLabel(_("Projection:")),
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(3, 0))
- self.sizer.Add(item=self.lprojection,
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(3, 1))
- self.sizer.Add(item=self.lproj4stringLabel,
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(4, 0))
- self.sizer.Add(item=self.lproj4string,
- flag=wx.ALIGN_LEFT | wx.ALL,
- border=5, pos=(4, 1))
- self.sizer.Add(item=(10,20),
- flag=wx.ALIGN_CENTER_HORIZONTAL | wx.ALL,
- border=5, pos=(5, 0), span=(1, 2))
- def OnEnterPage(self,event):
- """
- Insert values into text controls for summary of location creation options
- """
- # database = self.parent.startpage.grassdatabase
- # location = self.parent.startpage.location
- proj4string = self.parent.CreateProj4String()
- epsgcode = self.parent.epsgpage.epsgcode
- dtrans = self.parent.datumtrans
-
- global coordsys
- if coordsys not in ['proj', 'epsg']:
- self.lproj4stringLabel.Hide()
- self.lproj4string.Hide()
- self.lproj4stringLabel.SetLabel('')
- self.lproj4string.SetLabel('')
- else:
- self.lproj4string.Show()
- self.lproj4stringLabel.SetLabel(_("PROJ.4 definition:"))
- if coordsys == 'proj':
- ret, msg, err = gcmd.RunCommand('g.proj',
- flags = 'j',
- proj4 = proj4string,
- datumtrans = dtrans,
- location = location,
- getErrorMsg = True,
- read = True)
- elif coordsys == 'epsg':
- ret, msg, err = gcmd.RunCommand('g.proj',
- flags = 'j',
- epsg = epsgcode,
- datumtrans = dtrans,
- location = location,
- getErrorMsg = True,
- read = True)
-
- if ret == 0:
- projlabel = ''
- for line in msg.splitlines():
- projlabel = projlabel + '%s ' % line
- self.lproj4string.SetLabel(projlabel)
- else:
- wx.MessageBox(err, 'Error', wx.ICON_ERROR)
- self.lproj4string.Wrap(400)
-
- projdesc = self.parent.projpage.projdesc
- ellipsedesc = self.parent.ellipsepage.ellipsedesc
- datumdesc = self.parent.datumpage.datumdesc
- # self.ldatabase.SetLabel(database)
- # self.llocation.SetLabel(location)
- label = ''
-
- if coordsys == 'epsg':
- label = 'EPSG code %s (%s)' % (self.parent.epsgpage.epsgcode, self.parent.epsgpage.epsgdesc)
- self.lprojection.SetLabel(label)
- elif coordsys == 'file':
- label = 'matches file %s' % self.parent.filepage.georeffile
- self.lprojection.SetLabel(label)
- elif coordsys == 'wkt':
- label = 'matches file %s' % self.parent.wktpage.wktfile
- self.lprojection.SetLabel(label)
- elif coordsys == 'proj':
- label = ('%s, %s %s' % (projdesc, datumdesc, ellipsedesc))
- self.lprojection.SetLabel(label)
- elif coordsys == 'xy':
- label = ('XY coordinate system (not projected).')
- self.lprojection.SetLabel(label)
- elif coordsys == 'custom':
- label = ('%s' % self.parent.custompage.customstring)
- self.lprojection.SetLabel(label)
- def OnFinish(self, event):
- dlg = wx.MessageDialog(parent=self.wizard,
- message=_("Do you want to create GRASS location <%s>?") % location,
- caption=_("Create new location?"),
- style=wx.YES_NO | wx.YES_DEFAULT | wx.ICON_QUESTION)
- if dlg.ShowModal() == wx.ID_NO:
- dlg.Destroy()
- event.Veto()
- else:
- dlg.Destroy()
- event.Skip()
-
- if __name__ == "__main__":
- app = wx.App()
- gWizard = LocationWizard(None)
- # gWizard.Show()
- app.MainLoop()
|