Chris Nethery | 3 Oct 2004 05:32
Picon
Favicon

Storing structured, 'widget-specific-data', then loading it back in la ter


Hello everyone!

I have been working on the following for a while and just cannot get it to work correctly, so I am hoping that
someone could offer some advice.

I am trying to create a group of (re-usable) methods that take user input data and store it for future
reference, then reload it later to the same widget where it was originally created.  I wrote the following
program to try to get the process working.  The first button is supposed to store the data, and the second
button is meant to plug the data back into the widget.  I seem to be having difficulty plugging the data back
into the widget, because I cannot identify it(the widget) properly.  Any thoughts?

Thanking you in advance,

Chris Nethery

import marshal
import Tkinter
import Pmw

root = Tkinter.Tk()

screenWidth, screenHeight = root.maxsize()
screenSize = "%dx%d" % (screenWidth, screenHeight)
root.geometry(screenSize)
Pmw.initialise(root)

class DataManagement:

    def __init__(self,actualWidgetName,frame,widget,data):
(Continue reading)

Fredrik Lundh | 3 Oct 2004 08:42
Gravatar

Re: Storing structured, 'widget-specific-data', then loading it back in la ter

Chris Nethery wrote:

>        self.testButton = Tkinter.Button(self.f, font=(('Verdana'), '7'),
>            text='Test', command=self.getStoredData(self.widget))

to figure out why this doesn't work, consider what the following Python
constructs do:

    getStoredData(widget)

    self.getStoredData(self.widget)

    variable = self.getStoredData(self.widget) # what ends up in variable?

    function(keyword=self.getStoredData(self.widget)) # what's passed to the method?

    Widget(command=self.getStoredData(self.widget)) # what's passed to the constructor?

(hint: the "getStoredData(...)" part does the same thing, and returns the same
thing, in all five cases)

to work around this, you can add a local function:

    def my_callback(self=self):
        self.getStoredData(self.widget)
    self.testButton = Tkinter.Button(..., command=my_callback)

(this creates a callable object, my_callback, that has a reference to the "self"
instance variable.  when the object is called, it will call the right getStoredData
method with the right instance variable)
(Continue reading)

Chris Nethery | 5 Oct 2004 07:09
Picon
Favicon

Re: Re: Storing structured, 'widget-specific-data', then loading it back in la ter


Fredrik,

Sorry for the delay.  Needed to work on this one a bit.  I think you identified, rather quickly, an area I don't
really understand.  I have been struggling quite a bit with variable-passing (for starters) and function-calls.

For the first example, I think I'm accessing the widget's position in memory.  I think this is also true of the
second example, but I am making the variables accessible to other methods in the class.
For the third example, I believe that 'variable' becomes the function call.  For the fourth and fifth
examples, I am calling a function within another function and passing self.widget (as a variable) into
the function that is called... ...I think.

Also, I am very confused by:

1) The creation of a local function.  Why do I need to do this?  What are the rules that require one to create a
'sub'-function (nested function?) ?

2) The self=self statement in the my_callback function.  Doesn't the class already know that self=self,
and if not, why don't I have to do this every time I pass self to other functions in the class?

3) Lambda.  This may be more of a 'How does Lambda work?' question than anything, but here goes... ...With
Button(..., command=lambda: self.getStoredData(self.widget)), am I creating another local
function within the Button-widget method-call?  And, why do I need to do this, rather than call a variable
assigned to the function call?

Thank you for your help!

--Christopher Nethery
Martin Franklin | 5 Oct 2004 13:14
Picon

Re: Storing structured, 'widget-specific-data', then loading it back in la ter

On Sun, 3 Oct 2004 03:32:06 GMT, Chris Nethery <clnethery <at> juno.com> wrote:

>
> Hello everyone!
>
> I have been working on the following for a while and just cannot get it  
> to work correctly, so I am hoping that someone could offer some advice.
>
> I am trying to create a group of (re-usable) methods that take user  
> input data and store it for future reference, then reload it later to  
> the same widget where it was originally created.  I wrote the following  
> program to try to get the process working.  The first button is supposed  
> to store the data, and the second button is meant to plug the data back  
> into the widget.  I seem to be having difficulty plugging the data back  
> into the widget, because I cannot identify it(the widget) properly.  Any  
> thoughts?

<snipped code>

Chris,

This does not in anyway answer you questions.... but it may give you
some ideas :-)

 from Tkinter import *
import Pmw

class PickleMixin:
     def __init__(self):
         self.widgets = {}
(Continue reading)

stewart | 5 Oct 2004 17:50

Re: Storing structured, 'widget-specific-data', then loading it back in la ter

Quoting Chris Nethery <clnethery <at> juno.com>:

> 3) Lambda.  This may be more of a 'How does Lambda work?' question than
> anything, but here goes... ...With Button(..., command=lambda:
> self.getStoredData(self.widget)), am I creating another local function within
> the Button-widget method-call?  And, why do I need to do this, rather than
> call a variable assigned to the function call?

Chris, I've found that the use of lambda is a solution when you want to pass an
argument to a callback function.  If you simply create a command callback and
include an argument in its construction, that callback function gets executed as
soon as the GUI is drawn, which is not what we want!

so, you can create a button like so (inside some Class that creates the GUI):
b= Button(root, command = self.dosomething)) 
and will run properly, but you can't do the following:
b= Button(root, command = self.dosomething(arg))
Instead, you'd need to do this:
b= Button(root, command = lambda self=self, arg=arg: self.dosomething(arg))

Cameron Laird pointed out last week that you can also define an intermediate
function to pass the argument to instead of using a lambda function. 

Here's a little app (uses Pmw) that demonstrates three different ways of passing
arguments from a callback command:

----
title = 'Argument passing demonstration'

# Import Pmw from this directory tree.
(Continue reading)

Martin Franklin | 6 Oct 2004 08:58
Picon

Re: Storing structured, 'widget-specific-data', then loading it back in la ter

On Tue, 05 Oct 2004 09:50:50 -0600, <stewart <at> midtoad.homelinux.org> wrote:

> Quoting Chris Nethery <clnethery <at> juno.com>:
>
>> 3) Lambda.  This may be more of a 'How does Lambda work?' question than

[SNIP]

> class PrintOne:
>     def __init__(self, text):
>         self.text = text
>
>     def __call__(self):
>         '''this method will be automatically called when an instance of  
> the
> PrintOne object is created'''

Stewart,

I don't want to be pedantic ;-) but..... the __call__ method gets called  
when the instance of PrintOne is - called - not created.  It's the  
__init__ method that gets called when the instance is created.

Cheers
Martin.

--
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
stewart | 8 Oct 2004 03:02

Re: lambda and __call__ method

Quoting Martin Franklin <mfranklin1 <at> gatwick.westerngeco.slb.com>:

> I don't want to be pedantic ;-) but..... the __call__ method gets called  
> when the instance of PrintOne is - called - not created.  It's the  
> __init__ method that gets called when the instance is created.

Martin, you're right of course. I didn't write what I meant to say.

cheers,
Stewart
stewart | 8 Oct 2004 03:09

how to wait for user input?


hi all:

I've got a Tkinter app working. One of its methods opens a Pmw combo-box and
present a list of choices.  I've added buttons to delete choices, select
choices, and create a new choice. It's this latter button that is causing problems. 

When I create a choice, I invoke a method that asks for input on the name of a
choice using an easygui entry field. So far so good.  The next thing is to ask
the user to select one of two possible config setting for her choice; I'm doing
that with a top-level widget that contains a button for each of the two
settings.  The problem I'm having is that my method doesn't appear to stop and
wait for the user to press a button, but intead goes ahead to the next step,
which is to display the chosen config setting (which of course fails, since no
choice has yet been made). 

How do I get the method to stop and wait for the config setting to be made in
the toplevel window?  I think that I need the toplevel button to be modal, so
that as soon as it's drawn, execution stops on my choice-creation method.

If this seems too abstract, I can post a sample app that demonstrates the behaviour.

cheers
Stewart
Jeff Epler | 8 Oct 2004 03:32
Favicon

Re: how to wait for user input?

You can use .grab_set() (force keyboard and mouse events to a single window
in the application) and .wm_transient() (give the window the appearance
of a "transient" window aka "dialog" or "secondary window, and force it
to appear above the main application window in stacking order).

To wait for "something to happen", you can use wait_window (handles
events and returns when the window is destroyed) or wait_variable
(handles events and returns when the value of a variable is changed),
or you can have the command= of the OK and Cancel buttons perform the
action, destroy or hide the window, and release the grab, and use
neither of the above.

.grab_release() will let the main window handle events again.
Destroying the secondary window would automatically release grab.  I
don't know whether merely withdrawing it would.

Jeff
_______________________________________________
Tkinter-discuss mailing list
Tkinter-discuss <at> python.org
http://mail.python.org/mailman/listinfo/tkinter-discuss
stewart | 8 Oct 2004 06:43

Re: how to wait for user input?

Quoting Jeff Epler <jepler <at> unpythonic.net>:

> You can use .grab_set() 

Thanks, Jeff, that was just the tip I needed. I did a look-up on .grab_set() and
found some useful additional info in the pages at pythonware.com, e.g.
http://www.pythonware.com/library/tkinter/introduction/dialog-windows.htm and
also
http://www.pythonware.com/library/tkinter/introduction/x9374-event-processing.htm.

cheers
Stewart

Gmane