> I'm thinking I may need to add a trace that does the sync, not > override set().
To answer my own question and put it on the ML for future reference, creating classes for SQL-Alchemy SQL data types that bind a trace callback does indeed synchronize changes that happen to the widget onscreen with the SQL-A object. This is very convenient because my forms are all a single transaction in the DB, and when the changes are synced my save call is merely commit. Thanks. # ---------------------------------------------------------------------- class stringFieldVar(Variable): """Override Tk Variable class to allow sync and validation with SQLA objects""" def __init__(self, datum, field): self.datum = datum self.field = field super().__init__( value = self._tkConvert(getattr(self.datum, self.field, '')) ) self.trace("w", self.synchronizeWithSQL) def _tkConvert(self, value): """Convert to a string for Tk, only used on initial set from DB""" if value == None: result = '' else: result = str(value) return result def _sqlConvert(self, value): """Convert a Tk string back to SQL datatype, happens every widget refresh""" if value == '': result = None elif value: result = str(value) return result def synchronizeWithSQL(self, *args): """Convert data for DB type, the widget calls this repeatedly with changes""" try: # only update the sql object if the value is valid logger.debug("Testing {}, is '{}' valid?".format(self.field, self.get())) sqlValue = self._sqlConvert(self.get()) setattr(self.datum, self.field, sqlValue) logger.debug("Setting {}, converted '{}', to '{}'".format(self.field, self.get(), sqlValue)) except (AttributeError, TypeError): pass class intFieldVar(stringFieldVar): def _sqlConvert(self, value): if value == '': result = None elif value: result = int(value) return result class numericFieldVar(stringFieldVar): def _sqlConvert(self, value): if value == '': result = None elif value: result = D.decimal(value) return result class booleanFieldVar(stringFieldVar): def _tkConvert(self, value): """Convert to a string for Tk, only used on initial set from DB""" if value == None: result = '' elif value == True: result = '1' else: result = '0' return result def _sqlConvert(self, value): if value == '': result = None elif value == '1': result = True else: result = False return result class dateFieldVar(stringFieldVar): def _tkConvert(self, value): return '' if value == None else value.strftime("%Y/%m/%d") def _sqlConvert(self, value): if value == '': result = None elif value == 'now': result = 'now' elif value: result = time.strftime("%Y/%m/%d", value) return result class datetimeFieldVar(stringFieldVar): def _tkConvert(self, value): return '' if value == None else value.strftime("%Y/%m/%d %H:%M:%S") def _sqlConvert(self, value): if value == '': result = None elif value == 'now': result = 'now' elif value: result = time.strftime("%Y/%m/%d %H:%M:%S", value) return result ------------------------------------------------------------------ Russell Adams rlad...@adamsinfoserv.com PGP Key ID: 0x1160DCB3 http://www.adamsinfoserv.com/ Fingerprint: 1723 D8CA 4280 1EC9 557F 66E8 1154 E018 1160 DCB3 _______________________________________________ Tkinter-discuss mailing list Tkinter-discuss@python.org http://mail.python.org/mailman/listinfo/tkinter-discuss