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()

  

--
Signature.html
           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

Reply via email to