#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    9
    Rep Power
    0

    Return a value from a class. Very simple! But beyond me it seems.


    I have a simple example here taken from the Introduction to Tkinter from the pythonware site. I have just manipulated it a bit, but basically I want to return values from the dialog, and place them in the main app, I have chosen as simple example as I can manage to round up.

    Can anyone help me out here? I have an undergraduate Project to complete in just a few days so would like a swift as repsonse as possible.


    # File example2.py

    from Tkinter import *
    import tkSimpleDialog

    class MyDialog(tkSimpleDialog.Dialog):

    def body(self, master):

    Label(master, text="First:").grid(row=0)
    Label(master, text="Second:").grid(row=1)

    self.e1 = Entry(master)
    self.e2 = Entry(master)

    self.e1.grid(row=0, column=1)
    self.e2.grid(row=1, column=1)
    self.result=0

    def apply(self):
    first = string.atoi(self.e1.get())
    second = string.atoi(self.e2.get())
    self.result = first, second

    class App:

    def __init__(self,master):

    frame = Frame(master)
    frame.pack()

    self.quit_but = Button(frame, text="Quit", fg="red", command=frame.quit)
    self.quit_but.pack(side=LEFT)

    self.dialog_but = Button(frame, text="Dialog", command= self.run_dialog)
    self.dialog_but.pack(side=LEFT)

    self.entry = Entry(master, width=30)
    self.entry.pack(side=LEFT)

    def run_dialog(self):
    d = MyDialog(root)


    root = Tk()
    app=App(root)
    root.mainloop()
  2. #2
  3. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    You can't (as far as I know) return a value from a class directly. However you can return a value from one or more of the classes methods i.e. you could define a method that returns the sum of two instance variables.

    Code:
    >>> class A:
    ...     def __init__(self, x, y):
    ...         self.x = x
    ...         self.y = y
    ...     
    ...     def sumOfXandY(self):
    ...         return self.x + self.y
    ... 
    >>> a = A(10, 20)
    >>> a.sumOfXandY()
    30
    >>> 
    >>> class B:
    ...     return True
    ... 
      File "<stdin>", line 2
    SyntaxError: 'return' outside function
    >>>
    Note: You can't return a value from __init__() for obvious reasons, but you can get a similar result by overriding the __call__() method; this makes instances of the class callable like functions .

    Hope this helps,

    Mark.

    Comments on this post

    • CyBerHigh agrees
    programming language development: www.netytan.com Hula

  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    9
    Rep Power
    0
    See what your saying and have changed the code but it still doesnt work? I dont see what is wrong here, I am accessing the method through an instance of the class?

    # File example2.py

    from Tkinter import *
    import tkSimpleDialog

    class MyDialog(tkSimpleDialog.Dialog):

    def body(self, master):
    Label(master, text="First:").grid(row=0)
    Label(master, text="Second:").grid(row=1)

    self.e1 = Entry(master)
    self.e2 = Entry(master)

    self.e1.grid(row=0, column=1)
    self.e2.grid(row=1, column=1)

    def apply(self):
    first = int(self.e1.get())
    second = int(self.e2.get())
    self.result= first, second
    return self.result


    class App:

    def __init__(self,master):

    frame = Frame(master)
    frame.pack()

    self.quit_but = Button(frame, text="Quit", fg="red", command=frame.quit)
    self.quit_but.pack(side=LEFT)

    self.dialog_but = Button(frame, text="Dialog", command= self.run_dialog)
    self.dialog_but.pack(side=LEFT)

    self.text = Text(master, width=30)
    self.text.pack(side=LEFT)

    def run_dialog(self):
    d = MyDialog(root)
    self.text.insert(END, d.apply())



    root = Tk()
    app=App(root)
    root.mainloop()
    Originally Posted by netytan
    You can't (as far as I know) return a value from a class directly. However you can return a value from one or more of the classes methods i.e. you could define a method that returns the sum of two instance variables.

    Code:
    >>> class A:
    ...     def __init__(self, x, y):
    ...         self.x = x
    ...         self.y = y
    ...     
    ...     def sumOfXandY(self):
    ...         return self.x + self.y
    ... 
    >>> a = A(10, 20)
    >>> a.sumOfXandY()
    30
    >>> 
    >>> class B:
    ...     return True
    ... 
      File "<stdin>", line 2
    SyntaxError: 'return' outside function
    >>>
    Note: You can't return a value from __init__() for obvious reasons, but you can get a similar result by overriding the __call__() method; this makes instances of the class callable like functions .

    Hope this helps,

    Mark.
  6. #4
  7. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    Originally Posted by richardiontton@
    See what your saying and have changed the code but it still doesnt work? I dont see what is wrong here, I am accessing the method through an instance of the class?

    # File example2.py

    from Tkinter import *
    import tkSimpleDialog

    class MyDialog(tkSimpleDialog.Dialog):

    def body(self, master):
    Label(master, text="First:").grid(row=0)
    Label(master, text="Second:").grid(row=1)

    self.e1 = Entry(master)
    self.e2 = Entry(master)

    self.e1.grid(row=0, column=1)
    self.e2.grid(row=1, column=1)

    def apply(self):
    first = int(self.e1.get())
    second = int(self.e2.get())
    self.result= first, second
    return self.result


    class App:

    def __init__(self,master):

    frame = Frame(master)
    frame.pack()

    self.quit_but = Button(frame, text="Quit", fg="red", command=frame.quit)
    self.quit_but.pack(side=LEFT)

    self.dialog_but = Button(frame, text="Dialog", command= self.run_dialog)
    self.dialog_but.pack(side=LEFT)

    self.text = Text(master, width=30)
    self.text.pack(side=LEFT)

    def run_dialog(self):
    d = MyDialog(root)
    self.text.insert(END, d.apply())



    root = Tk()
    app=App(root)
    root.mainloop()
    I don't generally do GUI programming in Python but you seem to be returning a Tuple of two ints. You then insert the Tuple into self.text, which i presume is a Text field? Make sure this what you want. I would expect insert() to want a String rather than a Tuple.

    If your getting any Tracebacks/errors post them here since they might help track down the problem .

    Also, please read the sticky thread at the top of this forum regarding how to ask a question, about using CODE tags.

    Take care ,

    Mark.
    programming language development: www.netytan.com Hula

  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    9
    Rep Power
    0
    First of all I'd like to thank you for you help so far! Second lets assume that I dont return a tuple at all and I just return one value. A string like you stated, is actually what I want. I still cannot get the value back into the main App. The error message is not that helpful to me, at least to me.

    All I really want to see, is a dialog return a value, to another class. Not a built in dialog class type. A user defined class type like this one which uses the Dialog class from the Introduction to Tkinter tutorial on the pythonware site.

    Code:
    # File example2.py
    
    from Tkinter import *
    import tkSimpleDialog
    
    class MyDialog(tkSimpleDialog.Dialog):
    
        def body(self, master):
            Label(master, text="First:").grid(row=0)
            Label(master, text="Second:").grid(row=1)
    
            self.e1 = Entry(master)
            self.e2 = Entry(master)
    
            self.e1.grid(row=0, column=1)
            self.e2.grid(row=1, column=1)
           
    
        def apply(self):
            first=self.e1.get()
            return self.first
    
    class App:
    
        def __init__(self,master):
            frame = Frame(master)
            frame.pack()
    
            self.quit_but = Button(frame, text="Quit", fg="red", command=frame.quit)
            self.quit_but.pack(side=LEFT)
    
            self.dialog_but = Button(frame, text="Dialog", command= self.run_dialog)
            self.dialog_but.pack(side=LEFT)
    
            self.text = Text(master, width=30)
            self.text.pack(side=LEFT)
    
        def run_dialog(self):
            d = MyDialog(root)
            self.text.insert(END, d.apply())
    
    
    root = Tk()
    app=App(root)
    root.mainloop()

    The Error message is not that helpful I dont think. But Hey what do I know !

    Traceback (most recent call last):
    File "C:\Python24\lib\lib-tk\Tkinter.py", line 1345, in __call__
    return self.func(*args)
    File "C:\tkSimpleDialog.py", line 77, in ok
    self.apply()
    File "C:\example2.py", line 21, in apply
    return self.first
    AttributeError: MyDialog instance has no attribute 'first'



    I know there is no first instance variable in the MyDialog class but if I create a init method it simple doesnt compile because of the superclass I think?

    Originally Posted by netytan
    I don't generally do GUI programming in Python but you seem to be returning a Tuple of two ints. You then insert the Tuple into self.text, which i presume is a Text field? Make sure this what you want. I would expect insert() to want a String rather than a Tuple.

    If your getting any Tracebacks/errors post them here since they might help track down the problem .

    Also, please read the sticky thread at the top of this forum regarding how to ask a question, about using CODE tags.

    Take care ,

    Mark.
  10. #6
  11. No Profile Picture
    Contributing User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Nov 2004
    Posts
    394
    Rep Power
    51
    Hi!

    Here is the code that works for me
    Code:
    # File example2.py
    
    from Tkinter import *
    import tkSimpleDialog
    
    class MyDialog(tkSimpleDialog.Dialog):
    
        def body(self, master):
            Label(master, text="First:").grid(row=0)
            Label(master, text="Second:").grid(row=1)
    
            self.e1 = Entry(master)
            self.e2 = Entry(master)
    
            self.e1.grid(row=0, column=1)
            self.e2.grid(row=1, column=1)
           
    
        def apply(self):
            self.first = self.e1.get()
            self.second = self.e2.get()
    
    class App:
    
        def __init__(self,master):
            frame = Frame(master)
            frame.pack()
    
            self.quit_but = Button(frame, text="Quit", fg="red", command=frame.quit)
            self.quit_but.pack(side=LEFT)
    
            self.dialog_but = Button(frame, text="Dialog", command= self.run_dialog)
            self.dialog_but.pack(side=LEFT)
    
            self.text = Text(master, width=30)
            self.text.pack(side=LEFT)
    
        def run_dialog(self):
            d = MyDialog(root)
            self.text.insert(END, d.first)
            self.text.insert(END, d.second)
    
    
    root = Tk()
    app=App(root)
    root.mainloop()
    Regards, mawe
  12. #7
  13. Hello World :)
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2003
    Location
    Hull, UK
    Posts
    2,537
    Rep Power
    69
    In your code first is a local variable rather than an instance variable (a class attribute). You should be able to solve this by returning first rather than self.first, or even better you could do:

    Code:
        ...
        def apply(self):
            return self.e1.get()
        ...
    to avoid assigning the value to a variable at all.

    Mark.
    programming language development: www.netytan.com Hula

  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Feb 2005
    Posts
    9
    Rep Power
    0

    Smile


    I can see what you have done here, and I think you are a little genius in your own right. Well done and thanks again.

    I will definately be buying you a beer. You seem to be helping me out so often. Your so swift with getting to the codes problems.

    Thanks again mawe

    Originally Posted by mawe
    Hi!

    Here is the code that works for me
    Code:
    # File example2.py
    
    from Tkinter import *
    import tkSimpleDialog
    
    class MyDialog(tkSimpleDialog.Dialog):
    
        def body(self, master):
            Label(master, text="First:").grid(row=0)
            Label(master, text="Second:").grid(row=1)
    
            self.e1 = Entry(master)
            self.e2 = Entry(master)
    
            self.e1.grid(row=0, column=1)
            self.e2.grid(row=1, column=1)
           
    
        def apply(self):
            self.first = self.e1.get()
            self.second = self.e2.get()
    
    class App:
    
        def __init__(self,master):
            frame = Frame(master)
            frame.pack()
    
            self.quit_but = Button(frame, text="Quit", fg="red", command=frame.quit)
            self.quit_but.pack(side=LEFT)
    
            self.dialog_but = Button(frame, text="Dialog", command= self.run_dialog)
            self.dialog_but.pack(side=LEFT)
    
            self.text = Text(master, width=30)
            self.text.pack(side=LEFT)
    
        def run_dialog(self):
            d = MyDialog(root)
            self.text.insert(END, d.first)
            self.text.insert(END, d.second)
    
    
    root = Tk()
    app=App(root)
    root.mainloop()
    Regards, mawe

IMN logo majestic logo threadwatch logo seochat tools logo