Configuration Files and Tkinter--Possible?

W

W. eWatson

I'm converting a Tkinter program (Win XP) that uses widgets that allows the
user to change default values of various parameters like start and stop time
in hh:mm:ss, time of exposure in seconds, and whether certain options should
be on or off. The initial values are set in the code. I can pretty well
modify matters, so the values of parameters can be saved and restored from a
config file for use outside the widgets (dialogs). Basically, a list of
parameter names and values are kept in the file.

However, it is a tricky job to set up values for a widget that allows the
current values to appear in a dialog, and then return them to internal
storage for use elsewhere. The problem is in trying to make control variable
dynamic instead of as fixed code. There may be a solution, but it seems as
though someone should have had a similar problem in the past.

Is Python or Tkinter capable of solving this problem in some fashion? It may
be that there's another way to set and return values to the widget. However,
there seems to be an implication one can only do this with Tkinter control
variables? Another way of saying this is is why are control variables needed
anyway?

--
W. eWatson

(121.015 Deg. W, 39.262 Deg. N) GMT-8 hr std. time)
Obz Site: 39° 15' 7" N, 121° 2' 32" W, 2700 feet

Web Page: <www.speckledwithstars.net/>
 
G

Gabriel Genellina

I'm converting a Tkinter program (Win XP) that uses widgets that allows
the user to change default values of various parameters like start and
stop time in hh:mm:ss, time of exposure in seconds, and whether certain
options should be on or off. The initial values are set in the code. I
can pretty well modify matters, so the values of parameters can be saved
and restored from a config file for use outside the widgets (dialogs).
Basically, a list of parameter names and values are kept in the file.

Do you want to build a generic dialog (that is, do you want to *build* the
dialog depending on what you find in the file)? Or does the dialog already
exist? (In the former case, if you add a new parameter in the file, a new
widget -of an adequate type- is created)
I assume this is not the case, and you have a fixed dialog containing a
known set of widgets that represent a known set of parameters.

You need some object that stores the config values, and read/save them
from the config file. And a dialog that shows the config info and let the
user modify it. You don't need any StringVar/IntVar/whatever, if you don't
have to "track" changes to the variables (by example, a "zoom" slider
might provide feedback by zooming the image).
So in the "Options..." menu item in your application, you:

- create the dialog with the required widgets.
- call a method .setvalues(config) which receives a config object
with all the settings, and assigns them to each corresponding widget.
- have a method .getvalues(config) that does the inverse
operation: from widget contents into the config object.
- display the dialog (you must use a modal loop; see
http://effbot.org/tkinterbook/tkinter-dialog-windows.htm ). If you use
tkSimpleDialog, make sure the .apply() method calls .getvalues
- on exit, the config object contains the final values.
 
W

W. eWatson

Gabriel said:
....
don't have to "track" changes to the variables (by example, a "zoom"
slider might provide feedback by zooming the image).
So in the "Options..." menu item in your application, you:

- create the dialog with the required widgets.
- call a method .setvalues(config) which receives a config
object with all the settings, and assigns them to each corresponding
widget.
- have a method .getvalues(config) that does the inverse
operation: from widget contents into the config object.
- display the dialog (you must use a modal loop; see
http://effbot.org/tkinterbook/tkinter-dialog-windows.htm ). If you use
tkSimpleDialog, make sure the .apply() method calls .getvalues
- on exit, the config object contains the final values.
That's fine, but I think my problem boils down to one question. There seem
to be two ways to communicate with a dialog (I mean a collection of widgets
assembled in a window that requires the user enter various parameters,
integers, strings, yes/no button, etc.): 1. a callback and 2. control
variables. Which one should be used?

To be more explicit, look at this code from your source above
<http://effbot.org/tkinterbook/entry.htm>. (This is about the simplest
"dialog" one can have.) :
======================start
from Tkinter import *

master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
def callback():
print e.get()
b = Button(master, text="get", width=10, command=callback)
b.pack()
mainloop()
=======================end
Note that above this example, the author mentions:
"You can also bind the entry widget to a StringVar instance, and set or get
the entry text via that variable:

v = StringVar()
e = Entry(master, textvariable=v)
e.pack()

v.set("a default value")
s = v.get()
"
Why have two ways of doing this?


--
W. eWatson

(121.015 Deg. W, 39.262 Deg. N) GMT-8 hr std. time)
Obz Site: 39° 15' 7" N, 121° 2' 32" W, 2700 feet

Web Page: <www.speckledwithstars.net/>
 
G

Gabriel Genellina

That's fine, but I think my problem boils down to one question. There
seem to be two ways to communicate with a dialog (I mean a collection of
widgets assembled in a window that requires the user enter various
parameters, integers, strings, yes/no button, etc.): 1. a callback and
2. control variables. Which one should be used?

The simplest way that probably works. The one you feel most comfortable
with. The one best fits your application. There is no single answer.
To be more explicit, look at this code from your source above
<http://effbot.org/tkinterbook/entry.htm>. (This is about the simplest
"dialog" one can have.) : [...code...]
Note that above this example, the author mentions:
"You can also bind the entry widget to a StringVar instance, and set or
get the entry text via that variable:
Why have two ways of doing this?

You may have some related widgets, and want to keep them syncronized. By
example, a slider 0-100 and a text entry for some percentage. Moving the
slider changes the number displayed, and editing the number moves the
slider accordingly. There are other ways of doing the same: you may react
to some events in one widget, and alter the other accordingly. But:
- that requires that you know *which* events actually modify the value
- increases coupling between all your widgets (consider what happens when
you want to add an image showing the effect of moving the slider)

So, in some cases, it is more convenient to use bound variables. You may
consider this as a micro-application of the Model-View-Controller pattern.

That said, I seldom use bound variables (but I seldom write GUIs using
Tkinter either).
 
M

Marc 'BlackJack' Rintsch

That's fine, but I think my problem boils down to one question. There
seem to be two ways to communicate with a dialog (I mean a collection of
widgets assembled in a window that requires the user enter various
parameters, integers, strings, yes/no button, etc.): 1. a callback and
2. control variables. Which one should be used?

That's no two ways. There are two ways to read/set the text in the
`Entry`: using `Entry`'s methods or by passing a `Variable` instance and
use that object's methods. The callback is used in both cases.
To be more explicit, look at this code from your source above
<http://effbot.org/tkinterbook/entry.htm>. (This is about the simplest
"dialog" one can have.) :
======================start
from Tkinter import *

master = Tk()
e = Entry(master)
e.pack()
e.focus_set()
def callback():
print e.get()
b = Button(master, text="get", width=10, command=callback) b.pack()
mainloop()
=======================end
Note that above this example, the author mentions: "You can also bind
the entry widget to a StringVar instance, and set or get the entry text
via that variable:

v = StringVar()
e = Entry(master, textvariable=v)
e.pack()

v.set("a default value")
s = v.get()
"

In this example the callback is missing. Both operations, setting the
text and getting it back, are performed without any user interaction
directly one after another. Which just demonstrate how to use
`StringVar`.
Why have two ways of doing this?

Convenience. Setting a `Variable` that is used in a widget,
automatically updates the display of the widget. And `Variable`\s have a
method to add callbacks that get called when the content changes.

Ciao,
Marc 'BlackJack' Rintsch
 
W

W. eWatson

Gabriel said:
That's fine, but I think my problem boils down to one question. There
seem to be two ways to communicate with a dialog (I mean a collection
of widgets assembled in a window that requires the user enter various
parameters, integers, strings, yes/no button, etc.): 1. a callback and
2. control variables. Which one should be used?

The simplest way that probably works. The one you feel most comfortable
with. The one best fits your application. There is no single answer.
To be more explicit, look at this code from your source above
<http://effbot.org/tkinterbook/entry.htm>. (This is about the simplest
"dialog" one can have.) : [...code...]
Note that above this example, the author mentions:
"You can also bind the entry widget to a StringVar instance, and set
or get the entry text via that variable:
Why have two ways of doing this?

You may have some related widgets, and want to keep them syncronized. By
example, a slider 0-100 and a text entry for some percentage. Moving the
slider changes the number displayed, and editing the number moves the
slider accordingly. There are other ways of doing the same: you may
react to some events in one widget, and alter the other accordingly. But:
- that requires that you know *which* events actually modify the value
- increases coupling between all your widgets (consider what happens
when you want to add an image showing the effect of moving the slider)

So, in some cases, it is more convenient to use bound variables. You may
consider this as a micro-application of the Model-View-Controller pattern.

That said, I seldom use bound variables (but I seldom write GUIs using
Tkinter either).
Thanks, unfortunately I have no choice. I'm modifying a program that uses
Tkinter, and so not to take on extra work, I need to stick with Tkinter. The
author, for some reason, found it useful to use control variables.

In trying to add a configuration file to the code, the control variables
make it difficult. I have already coded the config file reading, writing,
and setting of variables (setattr came in very handy to get the fixed code
out of the way). However, to set them in the main dialog, is not easy,
because it uses code like self.colorVar = IntVar() and
dialog.colorVar.get(). To get rid of this written (hard) code, I have to
manufacture it somehow by forming it from the names found in the config
file, e.g., color=1. I'm aware of eval and exec, but wary of their use. It
seems like the solution to all this is not to use control variables, if
possible. Presently, I have no idea whether it is absolutely needed for the
program.

From what I can see on the web, and the few texts I have had access to, no
one makes a clear distinction between the two choices by way of words or
examples. This comes close:

From Tkinter reference: a GUI for Python
One special quality of a control variable is that it can be shared by a
number of different widgets, and the control variable can remember all the
widgets that are currently sharing it. This means, in particular, that if
your program stores a value v into a control variable c with its c.set(v)
method, any widgets that are linked to that control variable are
automatically updated on the screen.

I'm just getting into Tkinter, so that doesn't quite do it for me.

I originally mentioned, " ... it seems as though someone should have had a
similar problem in the past." What I meant was implementing a config file
arrangement with Tkinter. I was suggesting this seems nearly, if not,
impossible with control variables, so there must be another way. I think the
other way is described in the example I provided.

Well, I think it's now time to go back to the code, and see what I can do to
get rid of the control variables.

--
W. eWatson

(121.015 Deg. W, 39.262 Deg. N) GMT-8 hr std. time)
Obz Site: 39° 15' 7" N, 121° 2' 32" W, 2700 feet

Web Page: <www.speckledwithstars.net/>
 
G

Gabriel Genellina

Gabriel said:
En Wed, 04 Mar 2009 12:12:50 -0200, W. eWatson
That's fine, but I think my problem boils down to one question. There
seem to be two ways to communicate with a dialog (I mean a collection
of widgets assembled in a window that requires the user enter various
parameters, integers, strings, yes/no button, etc.): 1. a callback and
2. control variables. Which one should be used?
The simplest way that probably works. The one you feel most
comfortable with. The one best fits your application. There is no
single answer.
To be more explicit, look at this code from your source above
<http://effbot.org/tkinterbook/entry.htm>. (This is about the simplest
"dialog" one can have.) : [...code...]
Note that above this example, the author mentions:
"You can also bind the entry widget to a StringVar instance, and set
or get the entry text via that variable:
Why have two ways of doing this?
You may have some related widgets, and want to keep them syncronized.
By example, a slider 0-100 and a text entry for some percentage. Moving
the slider changes the number displayed, and editing the number moves
the slider accordingly. There are other ways of doing the same: you may
react to some events in one widget, and alter the other accordingly.
But:
- that requires that you know *which* events actually modify the value
- increases coupling between all your widgets (consider what happens
when you want to add an image showing the effect of moving the slider)
So, in some cases, it is more convenient to use bound variables. You
may consider this as a micro-application of the Model-View-Controller
pattern.
That said, I seldom use bound variables (but I seldom write GUIs using
Tkinter either).
Thanks, unfortunately I have no choice. I'm modifying a program that
uses Tkinter, and so not to take on extra work, I need to stick with
Tkinter. The author, for some reason, found it useful to use control
variables.

In trying to add a configuration file to the code, the control variables
make it difficult. I have already coded the config file reading,
writing, and setting of variables (setattr came in very handy to get the
fixed code out of the way). However, to set them in the main dialog, is
not easy, because it uses code like self.colorVar = IntVar() and
dialog.colorVar.get(). To get rid of this written (hard) code, I have to
manufacture it somehow by forming it from the names found in the config
file, e.g., color=1. I'm aware of eval and exec, but wary of their use.
It seems like the solution to all this is not to use control variables,
if possible. Presently, I have no idea whether it is absolutely needed
for the program.

You don't have to get rid of those bound variables. Just use them. Suppose
your config object has an attribute "color" and the dialog has "colorVar"
as you describe above. Then, in the setvalues method I menctioned in an
earlier post, you can do:

def setvalues(self, config):
self.colorVar.set(config.color)
# same for other vars

and make sure that, any way you handle the "Ok" button, the config obj is
updated.
From Tkinter reference: a GUI for Python
One special quality of a control variable is that it can be shared by a
number of different widgets, and the control variable can remember all
the widgets that are currently sharing it. This means, in particular,
that if your program stores a value v into a control variable c with its
c.set(v) method, any widgets that are linked to that control variable
are automatically updated on the screen.

I'm just getting into Tkinter, so that doesn't quite do it for me.

Maybe it helps to think of the control variable as a "model", and the
associated widgets as their "views" -- a micro Model-View-Controller.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,066
Latest member
VytoKetoReviews

Latest Threads

Top