Data Transfer Validator

The line "self.data = ..." needs to be moved before the use of the validators.

HTH, Phil

···

At 12:00 PM 10/26/2007, you wrote:

  I am having difficulty extrapolating the data transferring validator
example (listing 9.14, pages 286-288 in the wPIA book) to my application. I
will try to clearly explain what I've done and hope it's sufficient to have
someone point out my error(s).

  The main notebook panel has a button to add new records:

  self.fsAddButton = wx.Button(self, wx.ID_ADD, label='Add')
  self.Bind(wx.EVT_BUTTON, self.OnAdd, self.fsAddButton)

and the method, self.OnAdd, calls a dialog box:

    newSet = setDlg()
    result = newSet.ShowModal()
    if result == wx.ID_OK:
      # copy widget values into transfer names.
      self.fsName = newSet.fsTerm.GetValue()
      self.fsVar = newSet.fsPar.GetValue()
      self.fsSubComp = newSet.subName.GetValue()
      self.fsComp = newSet.compName.GetValue()
      self.fsNum = newSet.fsSeq.GetStringSelection()

I'd like to have self.fsVar, self.fsSubComp, and self.fsComp passed to the
dialog box, while self.fsName and self.fsNum is passed back from the dialog
box.

  This is the setDlg() class with the sizer commands omitted:

class setDlg(wx.Dialog): # Used to add or modify a fuzzy term set
  def __init__(self):
    wx.Dialog.__init__(self, None, wx.ID_ANY, "Add a New Term Set", size=(800, 400))

    <sizer data>

    seqLab = wx.StaticText(self, wx.ID_ANY, 'Sequence No.: ')
    seqList = ['1', '2', '3', '4', '5', '6', '7']
    self.fsSeq = wx.Choice(self, wx.ID_ANY, size=wx.Size(75, 25), choices=seqList,
                           style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                           validator=NotEmptyValidator())

    nameLab = wx.StaticText(self, wx.ID_ANY, 'Set Name: ')
    self.fsTerm = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                              style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                              validator=DataXferValidator(self.data, "termName"))

    parLab = wx.StaticText(self, wx.ID_ANY, 'Parent Variable: ')
    self.fsPar = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                             style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                             validator=DataXferValidator(self.data, "curParent"))

    subLab = wx.StaticText(self, wx.ID_ANY, 'Subcomponent: ')
    self.subName = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                               style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                               validator=DataXferValidator(self.data, "curSubComp"))

    compLab = wx.StaticText(self, wx.ID_ANY, 'Component: ')
    self.compName = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                                style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                                validator=DataXferValidator(self.data, "curComp"))

    line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)

    self.OkBut = wx.Button(self, wx.ID_OK, 'OK')
    self.CancelBut = wx.Button(self, wx.ID_CANCEL, 'Cancel')
    self.OkBut.SetDefault()

    <sizer stuff omitted>

    self.SetSizer(sizer)
    self.Fit()

    self.data = {"termName" : modFzySet().fzySet,
                 "curParent" : modFzySet().parVar,
                 "curSubComp" : modFzySet().subComp,
                 "curComp" : modFzySet().Comp}

  The error I see when I click the "Add" button is:

Traceback (most recent call last):
  File "/data1/eikos/fuzSetPage.py", line 489, in OnAdd
    newSet = setDlg()
  File "/data1/eikos/fuzSetPage.py", line 636, in __init__
    validator=DataXferValidator(self.data, "termName"))
AttributeError: 'setDlg' object has no attribute 'data'

  So, I have a syntax error that I don't see. I'd appreciate guidance on how
to have the setDlg dialog box see the data dictionary I set up (or a correct
dictionary if that's the problem).

Rich

Phil,

   Here's the validator and the class that uses it. Perhaps this makes it
easier to spot my syntax error.

class DataXferValidator(wx.PyValidator):
   def __init__(self, data, key):
     wx.PyValidator.__init__(self)
     self.data = data
     self.key = key

   def clone():
     return DataXferValidator(self.data. self.key)

   def Validate():
     return True

   def TransferToWindow(self):
     textCtrl = self.GetWindow()
     textCtrl.SetValue(self.data.get(self.key, ""))
     return True

   def TransferFromWindow():
     textCtrl = self.GetWindow()
     self.data[self.key] = textCtrl.GetValue()
     return True

···

On Fri, 26 Oct 2007, Phil Mayes wrote:

Don't know; I can't make this work because the validator code is missing. It looks correct to construct self.data at that point.

-----------------------------------------------------------------

class setDlg(wx.Dialog):
   def __init__(self):
     wx.Dialog.__init__(self, None, wx.ID_ANY, "Add a New Term Set", size=(800, 400))

     sizer = wx.BoxSizer(wx.VERTICAL)
     box0 = wx.BoxSizer(wx.HORIZONTAL)
     box1 = wx.BoxSizer(wx.HORIZONTAL)
     box2 = wx.BoxSizer(wx.HORIZONTAL)
     box3 = wx.BoxSizer(wx.HORIZONTAL)
     box4 = wx.BoxSizer(wx.HORIZONTAL)
     buttonBox = wx.BoxSizer(wx.HORIZONTAL)

     self.data = {"termName" : modFzySet().fzySet,
                  "curParent" : modFzySet().parVar,
                  "curSubComp" : modFzySet().subComp,
                  "curComp" : modFzySet().Comp}

     seqLab = wx.StaticText(self, wx.ID_ANY, 'Sequence No.: ')
     seqList = ['1', '2', '3', '4', '5', '6', '7']
     self.fsSeq = wx.Choice(self, wx.ID_ANY, size=wx.Size(75, 25), choices=seqList,
                            style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                            validator=NotEmptyValidator())

     nameLab = wx.StaticText(self, wx.ID_ANY, 'Set Name: ')
     self.fsTerm = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                               style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                               validator=DataXferValidator(self.data, "termName"))

     parLab = wx.StaticText(self, wx.ID_ANY, 'Parent Variable: ')
     self.fsPar = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                              style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                              validator=DataXferValidator(self.data, "curParent"))

     subLab = wx.StaticText(self, wx.ID_ANY, 'Subcomponent: ')
     self.subName = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                                style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                                validator=DataXferValidator(self.data, "curSubComp"))

     compLab = wx.StaticText(self, wx.ID_ANY, 'Component: ')
     self.compName = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                                 style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                                 validator=DataXferValidator(self.data, "curComp"))

     line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)

     self.OkBut = wx.Button(self, wx.ID_OK, 'OK')
     self.CancelBut = wx.Button(self, wx.ID_CANCEL, 'Cancel')
     self.OkBut.SetDefault()

     box0.Add(seqLab, 0, wx.ALL, 5)
     box0.Add(self.fsSeq, 0, wx.ALL, 5)
     box1.Add(nameLab, 0, wx.ALL, 5)
     box1.Add(self.fsTerm, 0, wx.ALL, 5)
     box2.Add(parLab, 0, wx.ALL, 5)
     box2.Add(self.fsPar, 0, wx.ALL, 5)
     box3.Add(subLab, 0, wx.ALL, 5)
     box3.Add(self.subName, 0, wx.ALL, 5)
     box4.Add(compLab, 0, wx.ALL, 5)
     box4.Add(self.compName, 0, wx.ALL, 5)
     buttonBox.Add(self.OkBut, 0, wx.ALL, 5)
     buttonBox.Add(self.CancelBut, 0, wx.ALL, 5)

     sizer.Add(box0, 1, wx.EXPAND|wx.ALL, 5)
     sizer.Add(box1, 1, wx.EXPAND|wx.ALL, 5)
     sizer.Add(box2, 1, wx.EXPAND|wx.ALL, 5)
     sizer.Add(box3, 1, wx.EXPAND|wx.ALL, 5)
     sizer.Add(box4, 1, wx.EXPAND|wx.ALL, 5)
     sizer.Add(line, 1, wx.GROW|wx.RIGHT|wx.TOP, 5)
     sizer.Add(buttonBox, 1, wx.CENTER|wx.ALL, 5)

     self.SetSizer(sizer)
     self.Fit()

Thanks,

Rich

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Phil,

   OK. Yes, modFzySet is the class that calls the dialog class. I'm not sure
what arguments need to be passed, but I'll work with this.

Thanks,

Rich

···

On Sat, 27 Oct 2007, Phil Mayes wrote:

Didn't try it because I think Christian K nailed it last night when he
wrote "What is modFzySet? I bet it's a class which you're instantiating in
that line and you're not passing the required arguments."

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863

Rich Shepard escribió:

Didn't try it because I think Christian K nailed it last night when he
wrote "What is modFzySet? I bet it's a class which you're instantiating in
that line and you're not passing the required arguments."

Phil,

  I've not seen Christian's message, but my reading and trials tell me that
my problem is not knowing how to reference attributes defined in one class
(modFzySet) in the data dictionary defined in a second class, setDlg(), for
use by the validator defined in a third class, dataXferValidator().

  The first class, modFzySet() instantiates an instance of the second class
like this:

  newSet = setDlg()

I use to do something like:

data = {"termName" : fzySet,
              "curParent" : parVar,
              "curSubComp" : subComp,
              "curComp" : Comp}

newSet = setDlg(data)
newSet.ShowModal()
...

class setDlg(wx.Dialog):
  def __init__(self, data):
    wx.Dialog.__init__(self, None, wx.ID_ANY, "Add a New Term Set", size=(800, 400))
    self.data = data

···

On Sat, 27 Oct 2007, Phil Mayes wrote:

but that instance name is visible only within modFzySet(). So are the widget
names I'm trying to pass into and from newSet. However, I've assigned the
dataXferValidator() class to the widgets in newSet.

  As a result, I'm confused and my Python books don't give me insight into
the proper way to use the validator in this situation. That's because the
books discuss class attribute inheritance within an inheritance hierarchy,
and that's not what I have. modFuzSet() is an instance of wx.Panel, and
setDlg() is an instance of wx.Dialog.

  I suspect, from re-reading listing 9.14, that the validator functions are
not properly constructed for my need.

Rich

If you're saying that the constructor for one class (modFzySet) creates an instance of a second class (setDlg) and the constructor for the second class creates an instance of the first class, then that can't be done. Just think Xmas presents: you can put box A into bag B, or vice versa, but not both at once.

But I may have misunderstood, and anyway, it's not the problem you currently have. For that, I still think you need to check the constructors by adding
     aaa = modFzySet().fzySet
     bbb = modFzySet().parVar
     ccc = modFzySet().subComp
     ddd = modFzySet().Comp
and seeing if that works.

HTH, Phil

···

At 12:42 PM 10/27/2007, you wrote:

On Sat, 27 Oct 2007, Phil Mayes wrote:

Didn't try it because I think Christian K nailed it last night when he
wrote "What is modFzySet? I bet it's a class which you're instantiating in
that line and you're not passing the required arguments."

Phil,

  I've not seen Christian's message, but my reading and trials tell me that
my problem is not knowing how to reference attributes defined in one class
(modFzySet) in the data dictionary defined in a second class, setDlg(), for
use by the validator defined in a third class, dataXferValidator().

  The first class, modFzySet() instantiates an instance of the second class
like this:

  newSet = setDlg()

but that instance name is visible only within modFzySet(). So are the widget
names I'm trying to pass into and from newSet. However, I've assigned the
dataXferValidator() class to the widgets in newSet.

attached is a working version, with some hacks in order to make it a *runnable example*.

also I point some noted on the code below.

Rich Shepard escribió:

  def OnAdd(self, event):
    self.fzySetType.SetStringSelection('Bell Curve')
    self.domLeft.SetValue(0.00)
    self.domRight.SetValue(100.00)
    self.baseLeft.SetValue(0.00)
    self.baseRight.SetValue(100.00)
    self.inflexPt.SetValue(0.50)
    self.topLeft.SetValue(0.00)
    self.topRight.SetValue(100.00)
    self.midPt.SetValue(50.00)
    self.span.SetValue(25.00)
    self.maxHt.SetValue(1.00)

    data = {"fsPar" : self.dispVar,
            "subName" : self.dispSub,
            "compName" : self.dispComp}
                                                                                                                                  newSet = setDlg(data)
    result = newSet.ShowModal()
    if result == wx.ID_OK:
  

a block of code is missing here.
you should include newSet.Destroy() in that block.

# ------------------------------------------------------------------------------
class setDlg(wx.Dialog):
  def __init__(self, data):
    wx.Dialog.__init__(self, None, wx.ID_ANY, "Add a New Term Set", size=(800, 400))
    self.data = data
              sizer = wx.BoxSizer(wx.VERTICAL)
    box0 = wx.BoxSizer(wx.HORIZONTAL)
    box1 = wx.BoxSizer(wx.HORIZONTAL)
    box2 = wx.BoxSizer(wx.HORIZONTAL)
    box3 = wx.BoxSizer(wx.HORIZONTAL)
    box4 = wx.BoxSizer(wx.HORIZONTAL)
    buttonBox = wx.BoxSizer(wx.HORIZONTAL)
                                                  seqLab = wx.StaticText(self, wx.ID_ANY, 'Sequence No.: ')
    seqList = ['1', '2', '3', '4', '5', '6', '7']
    self.fsSeq = wx.Choice(self, wx.ID_ANY, size=wx.Size(75, 25), choices=seqList,
                           style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                                                                                                                validator=NotEmptyValidator())
    nameLab = wx.StaticText(self, wx.ID_ANY, 'Set Name: ')
    self.fsTerm = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                              style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER)
                                                                                                                                                                                            parLab = wx.StaticText(self, wx.ID_ANY, 'Parent Variable: ')
    self.fsPar = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                             style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                             validator=DataXferValidator(self.data, "fsPar"))
                                                                                                                                                                                                                                                              subLab = wx.StaticText(self, wx.ID_ANY, 'Subcomponent: ')
    self.subName = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                               style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                               validator=DataXferValidator(self.data, "subName"))
                                                                                                                                                                                                                                                                                                                                    compLab = wx.StaticText(self, wx.ID_ANY, 'Component: ')
    self.compName = wx.TextCtrl(self, wx.ID_ANY, size=wx.Size(125, 25),
                                style=wx.TAB_TRAVERSAL|wx.RAISED_BORDER,
                                validator=DataXferValidator(self.data, "compName"))
                                                                                                                                                                                                                                                                                                                                                                                                                line = wx.StaticLine(self, -1, size=(20,-1), style=wx.LI_HORIZONTAL)
    self.OkBut = wx.Button(self, wx.ID_OK, 'OK')
    self.CancelBut = wx.Button(self, wx.ID_CANCEL, 'Cancel')
    self.OkBut.SetDefault()
        box0.Add(seqLab, 0, wx.ALL, 5)
    box0.Add(self.fsSeq, 0, wx.ALL, 5)
    box1.Add(nameLab, 0, wx.ALL, 5)
    box1.Add(self.fsTerm, 0, wx.ALL, 5)
    box2.Add(parLab, 0, wx.ALL, 5)
    box2.Add(self.fsPar, 0, wx.ALL, 5)
    box3.Add(subLab, 0, wx.ALL, 5)
    box3.Add(self.subName, 0, wx.ALL, 5)
    box4.Add(compLab, 0, wx.ALL, 5)
    box4.Add(self.compName, 0, wx.ALL, 5)
        buttonBox.Add(self.OkBut, 0, wx.ALL, 5)
    buttonBox.Add(self.CancelBut, 0, wx.ALL, 5)
        sizer.Add(box0, 1, wx.EXPAND|wx.ALL, 5)
    sizer.Add(box1, 1, wx.EXPAND|wx.ALL, 5)
    sizer.Add(box2, 1, wx.EXPAND|wx.ALL, 5)
    sizer.Add(box3, 1, wx.EXPAND|wx.ALL, 5)
    sizer.Add(box4, 1, wx.EXPAND|wx.ALL, 5)
    sizer.Add(line, 1, wx.GROW|wx.RIGHT|wx.TOP, 5) sizer.Add(buttonBox, 1, wx.CENTER|wx.ALL, 5)
    self.SetSizer(sizer)
    self.Fit()

#------------------------------------------------------
class DataXferValidator(wx.PyValidator):
  def __init__(self, data, key):
      wx.PyValidator.__init__(self)
      self.data = data
      self.key = key
                def clone():
    return DataXferValidator(self.data. self.key)
  

it's name is Clone (capitalized), It misses the self parameter. There's also a typo: parameters are not separated by a coma (,)

                      def Validate():
    return True
  
def Validate(self, parent):

                            def TransferToWindow(self):
    textCtrl = self.GetWindow()
    textCtrl.SetValue(self.data.get(self.key, ""))
    return True
                                          def TransferFromWindow():
    textCtrl = self.GetWindow()
    self.data[self.key] = textCtrl.GetValue()
    return True

missing self attribute also here.

jonhattan

rshepard.code.py (5.96 KB)

···

------------------------------------------------------------------------

---------------------------------------------------------------------
To unsubscribe, e-mail: wxPython-users-unsubscribe@lists.wxwidgets.org
For additional commands, e-mail: wxPython-users-help@lists.wxwidgets.org

Werner,

   Great catch! Thank you very much. I did not see that despite looking at
the code several times. Fresh eyeballs are so valuable.

Rich

···

On Mon, 29 Oct 2007, Werner F. Bruhin wrote:

I think you have some problems in your validator class.

--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc. | Accelerators(TM)
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863