[Tutor] Configuration File, Tkinter, IntVars--Manufacturing Variables

Kent Johnson kent37 at tds.net
Thu Mar 5 00:00:36 CET 2009


On Tue, Mar 3, 2009 at 2:54 PM, Wayne Watson
<sierra_mtnview at sbcglobal.net> wrote:
> I see my post of yesterday, "Maintaining the Same Variable Type--Tkinter",
> went over like a lead balloon. :-)
> (Note though the Myth Busters TV series successfully built and flew a lead
> balloon.)
>
> Let's see if I can really simplify what I'm after. I've pulled the
> essentials out of the original larger program I'm trying to modify. 2000
> lines down to 80. I've only added a few lines of my own, and changed the
> menu and dialog content. Although I've heavily modified the original code to
> accept a config file, and set up variable to initialize the widgets, trying
> to bridge some code in the Enter_Data_Dialog and Set_Enter_Data objects
> control variable code is where the trouble lays for completing the
> modifications.
>
> The code below puts up a window with one menu and two submenus items,  Enter
> Data, and Exit. Select Enter Data and put in an integer number. It all works
> fine. Basically, what I want to do is eliminate code like
> dialog.anumberVar.get() and replace it by constructing the appropriate names
> for the config file. In this case, the config file might contain:
>     anumber = 123

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


More information about the Tutor mailing list