GUI/data object oriented design question

george young gry at ll.mit.edu
Wed Nov 28 00:03:04 CET 2001


[python2.1, pygtk-0.6.6, gtk+-1.2.7, postgres-7.1, pygresql-3.2] 
This is a fairly basic object-oriented design question, I think,
about the class structure of data objects and respective GUI elements.
How do I subclass an entire heirarchy of objects?  All the data is text,
with three levels of hierarchy, and resides in a relational DB.
In some contexts, data must be manipulated without any graphics.
Note especially the kludge of "data_type", "step_type", etc:

class Datum: ...
class DatumWin(Datum): ....

class Run:
	data_type = Datum
	step_type = Step
	def __init__(self, name):
		name,user = db.fetch_run_hdr(name)
		self.name = self.data_type(name)
		self.user= self.data_type(user)
		for s in db.fetch_run_steps(name):
			steps.append(step_type(*s))

class Step:
	data_type = Datum
	substep_type = SubStep
	def __init__(self, name, description):
		self.name = self.data_type(name)
		self.description = self.data_type(description)
		for ss in db.fetch_step_substeps(step_id):
			self.steps.append(self.substep_type(*ss))

class SubStep:
	data type = Datum
	param_type = Param
	def __init__(self, run_id, step_id, seq):
		self.run_id, self.step_id, self.seq = run_id, step_id, seq
		for p in db.fetch_substep_params(step_id):
			self.params.append(self.param_type(*p))

But in case I need a GUI representation of the run, I want to do:

class RunWin(Run, gtk.ScrolledWindow):
	data_type = DatumWin
	step_type = StepWin
	def __init__(self, name):
		Run.__init__(self, name)
		self.name.set_label('Name')
		self.user.set_label('User')
		for n in range(len(self.steps)):
			self.steps[n].set_label(`n`)
			self.steps[n].name.connect('activated', act_cb)
...
	
I think this may work, but the explicit manipulation of "data_type" etc.
seems pretty kludgy.  Is there some "pattern" that solves this?

My first thought was for each GUI object to have a reference to it's
respective data object, e.g. a StepWin has a Step reference.  But then the
Run has to maintain it's own parallel list of Steps, while the RunWin has
it's list of StepWins.  And the resulting references needed by 
callbacks get very ugly.

I've been staring at this stuff far too long and would be very grateful
for some suggestions.  I hope I've explained the problem enough...

George Young,  Rm. L-204                g r y @ ll.mit.edu
MIT Lincoln Laboratory
244 Wood St.
Lexington, Massachusetts  02420-9108    (781) 981-2756



More information about the Python-list mailing list