tags:

views:

151

answers:

2

I know this kind of question gets asked all the time but either i've been unable to come across the answer i need, or i've been unable to understand it when i did.

I want to be able to do something like:

spam = StringVar()
spam.set(aValue)
class MyScale(Scale):
    def __init__(self,var,*args,**kwargs):
        Scale.__init__(self,*args,**kwargs)
        self.bind("<ButtonRelease-1>",self.getValue)
        self.set(var.get())
    def getValue(self,event):
        ## spam gets changed to the new value set 
        ## by the user manipulating the scale
        var.set(self.get)
eggs = MyScale(spam,*args,**kwargs)
eggs.pack()

Of course, i get back "NameError: global name 'var' is not defined."

How do i get around the inability to pass arguments to getValue? I've been warned against using global variables but is that my only option? Is it setting up a separate scale class for each variable i want to change? I get the feeling i'm missing something thats right under my nose...

edit: is this what you mean?

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python26\lib\lib-tk\Tkinter.py", line 1410, in __call__
    return self.func(*args)
  File "C:\...\interface.py", line 70, in getValue
    var.set(self.get)
NameError: global name 'var' is not defined

Sorry, I've only been programming a month and some of the jargon still escapes me.

+1  A: 

Let's look at this method function

    def getValue(self,event):
        ## spam gets changed to the new value set 
        ## by the user manipulating the scale
        var.set(self.get)

The var.set(self.get) line has exactly two local variables available:

  • self
  • event

The variable var is not local to this method function. Perhaps it was used elsewhere in the class or script, but it's not local here.

It may, possibly, be global, but that's a bad practice.

I'm not sure why you'd think the variable var would be known in this context.

S.Lott
I understand that it wouldn't be known, i guess i'm asking how to get it to be known, not only as a reference to some variable but as as a variable i can change for the whole program.
You don't want a variable "for the whole program". You want a variable for this object to manipulate. Other objects in the whole program may also manipulate this. Multiple objects sharing a reference is good. Global variables are bad. The difference is one of focus and allocation of responsibility.
S.Lott
+2  A: 

Please give this a shot.

Lots of example code out there generously uses globals, like your "var" variable.

I have used your var argument to act as a pointer back to the original spam object; assigned to self.var_pointer within the MyScale class.

The code below will change the value of 'spam' (and 'eggs') on the scale's ButtonRelease.

You can check out the value by typing eggs.get() or spam.get() to see the changed value.

from Tkinter import *
root = Tk()

aValue = "5"
spam = StringVar()
spam.set(aValue)

class MyScale(Scale):
    def __init__(self,var,*args,**kwargs):
        self.var_pointer = var
        Scale.__init__(self,*args,**kwargs)
        self.bind("<ButtonRelease-1>",self.getValue)
        self.set(var.get())
    def getValue(self,event):
        ## spam gets changed to the new value set 
        ## by the user manipulating the scale
        self.var_pointer.set(self.get())

eggs = MyScale(spam)
eggs.pack(anchor=CENTER)
tom
+1, saving a reference to var as an instance variable is clearly the right approach.
Alex Martelli
that's exactly what i wanted, thank you.