[PEAK] Trellis-ified wx Dialog
Phillip J. Eby
pje at telecommunity.com
Thu Jul 19 14:43:51 EDT 2007
At 10:13 AM 7/19/2007 -0700, Grant Baillie wrote:
>I've attached a small I example I quickly cons'ed up to use Trellis
>synchronization in a data-binding style wxDialog. Essentially, it's a
>wx.Dialog-ified version of the TempConverter example in the Trellis
>README.
>
>Comments welcome ... The code (and dialog!) both have their
>uglinesses: In particular, I could certainly seeing mixing in Cells
>and wx classes rather than the existing approach.
My main suggestion would be to make each field (c, f, and summary) in
its own rule, e.g.:
@trellis.rule
def cField(self):
cField = ...
cField.Bind(...)
return cField
Rather than having a single rule for "fields". This would get rid of
the need for the "if" calls in other rules.
I probably also would've put all the updates to the widgets in a
single rule, just for brevity's sake, although that approach wouldn't
make sense for a more sophisticated example. Of course, for
something more sophisticated, you'd use some sort of
text-editing-field object linked directly to the cells in question,
perhaps something like:
class EditBridge(trellis.Component):
cell = None
widget = None
def __init__(self, **kw):
super(EditBridge, self).__init__(**kw)
self.widget.Bind(wx.EVT_KILL_FOCUS, self.write)
@trellis.rule
def read(self):
self.widget.SetValue(self.cell.value)
def write(self, event):
self.cell.value = self.widget.GetValue()
Then your main code could be reduced to something like this (omitting
the TemperatureDialog class):
class ConverterDialog(trellis.Component):
trellis.rules(
fField = lambda self: EditBridge(
widget = wx.xrc.XRCCTRL(self.dialog, "ID_F_FIELD"),
cell = self.converter.__cells__['F']
),
cField = lambda self: EditBridge(
widget = wx.xrc.XRCCTRL(self.dialog, "ID_C_FIELD"),
cell = self.converter.__cells__['C']
),
summary = lambda self: wx.xrc.XRCCTRL(self.dialog, "ID_SUMMARY"),
converter = lambda self: TempConverter(),
dialog = lambda self: TemperatureDialog(parent=None, id=-1)
)
@trellis.rule
def updateSummary(self):
if self.converter.F > 80.0:
self.summary.SetLabel(u"Phew!")
elif self.converter.C < 5.0:
self.summary.SetLabel(u"Brrr!")
else:
self.summary.SetLabel(u"")
if __name__ == "__main__":
app = wx.PySimpleApp(redirect=False)
ConverterDialog().dialog.Show()
app.MainLoop()
As you can see, having a little bit of glue helps a lot -- I believe
the result is shorter than the original, even if you include the new
EditBridge class.
By the way, the general rule of Trellis programming is that if you're
assigning to cells in a rule, you're probably doing something
wrong. (That is, you're not thinking declaratively enough.) The
revised version here only assigns cells from non-Trellis code (i.e.,
widget callbacks), which is how things should almost always be.
More information about the PEAK
mailing list