Yes, you have the idea. Here's about the simplest summary I wrote to
another person that I can muster. It may clarify matters. The anumber
I'm referring to is in the 80 line version I posted to start this
thread. ========================A Simple Explanation (I hope) ======== Consider some of the new code I put into the original 2000 line program written by someone else. def SetConfigDictionary(): config_var_list = [ {'name':'gray_scale', 'value':True, 'type': BOO}, # {'name':'color', 'value':None, 'type': INT}, # gray_scale, ambiguity {'name':'post_event_stack', 'value':False, 'type': BOO}, {'name':'post_event_format', 'value':'Tiff 2', 'type': STR}, {'name':'show_real_time', 'value':False, 'type': BOO}, {'name':'hourly_rate', 'value':12, 'type': INT}, {'name':'slowdown', 'value':1, 'type': INT}, {'name':'start_time', 'value':'18:00:00', 'type': TIM}, {'name':'stop_time', 'value':'10:00:00', 'type': TIM}, blah, blah, ... ] Like the self.anumber = 150 one will find in the original program self.hourly_rate = 12, but it's now replaced by running through that conf_var_list, and forming from the entry there something like: setattr(self, varName, varValue), where varName is "hourly_rate" and varValue is 12. That is, the program code no longer contains the explicity, hard coded, self.hourly_rate = 12. Eventually, all this info is used to initialize the big dialog in the image I sent (See a later response to Alan). It all works just fine. However, what has temporaily stumped me is how to retrieve any data the user enters without use of the hard coded control variable references. That activity takes place after (in 80 line version) dialog = Enter_Data_Dialog( self.master, sdict ). Actually, I think I know, but haven't had the time to work out the details. ===========================End of Simple============= It looks like your sample code code has the right idea, but the hang up with the original code is getting entered values back to the main program and available globally through it. The trick in your code, I think, is to get the data back the user entered, and set the main program's global variables (to mimic the original program). I'm stuck with the original concept of the main code setting self.hourly_rate to the new value to, say, 15 in the Dialog setup that calls the Dialog GUI. That is, when the Dialog returns, the code must set self.hourly_rate to 15. I may not like that, but that's the way the author designed it. I do not want to rewrite lots of code because of it. So instead of the code after the return to the from Dialog being hard coded, I need to construct executable statements from the list above to do the job. Kent Johnson wrote: ... I've stayed out of this because I don't really understand what you are trying to do. But I *think* what you are looking for is a data-driven GUI. Rather than hard-coding a bunch of variable names and types, you want to build a gui based on a description of the data.Here is a program that might give you some ideas about how to abstract your problem. I don't expect it to exactly (or even closely) do what you want but maybe it will point you in a useful direction. The heart of it is the initial classes, which abstract the creation of a gui and retrieval of a typed value, and the 'values' list in class App, which is the definition of the values to display and their types. The gui can be extended with additional entry lines simply by adding more entries to the values list. Kent from Tkinter import * # These classes encapsulate creating a gui element and retrieving a typed value from it # The constructors create the elements, the get() methods return values class TextWidget(object): def __init__(self, master, label, row): Label(master, text=label).grid(row=row, sticky=W) self.entry = Entry(master) self.entry.grid(row=row, column=1) class StringWidget(TextWidget): def get(self): return self.entry.get() class IntWidget(TextWidget): def get(self): # This will blow up if the entry is not a valid integer # Better would be to validate or constrain the input value = self.entry.get() return int(value) if value else 0 class BoolWidget(object): def __init__(self, master, label, row): self.var = IntVar() cb = Checkbutton(master, text=label, variable=self.var) cb.grid(row=row, columnspan=2, sticky=W) def get(self): return bool(self.var.get()) class App: def __init__(self, master): # List of parameter name, parameter description, widget type values = [ ('name', 'Your name:', StringWidget), ('age', 'Your age:', IntWidget), ('subscribe', 'Send emails', BoolWidget), ] # Create the widgets row = 0 self.widgets = {} for name, desc, widget in values: self.widgets[name] = widget(master, desc, row) row += 1 # Button to print values Button(master, text="Show", command=self.show).grid(row=row) def show(self): for name, widget in self.widgets.items(): print name, type(widget.get()), widget.get() root = Tk() app = App(root) root.mainloop() --
Wayne Watson (Watson Adventures, Prop., Nevada City, CA) (121.01 Deg. W, 39.26 Deg. N) GMT-8 hr std. time) “In mathematics you don't understand things. You just get used to them.” -- John Von Neumann (P.S. The same is true in life.) Web Page: <www.speckledwithstars.net/> |
_______________________________________________ Tutor maillist - Tutor@python.org http://mail.python.org/mailman/listinfo/tutor