1

I am new in Python classes and trying to write an interface for a scientific code via Tkinter. But I can not call a function (which is in another class and opens a different frame) from a class or function. I have been searching for more than 2 days but could not find an answer to my case. If you explain like explaining a child I would be very happy since I don't know much technical details.

My code structure is like:

class first_class(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
                 ....
        def WhateverFunction():
           "do sth"
class second_class(tk.Tk):

   def __init__(self, parent, controller):
       tk.Frame.__init__(self, parent)
               .....
       **I want to use "WhateverFunction" here** 
               .....

so basically, I can not access that function from another class.

The searches I found online like Python using methods from other classes method. Bu This did not solve my problem. It is maybe because I am working with different Tkinter frames. I do not now... Thanks already, cheers!

hakan sert
  • 13
  • 3
  • you need to inherit from the first class you have made if you want to use that function. `class second_class(first_class):` or call the class method from within `first_class().WhateverFunction()` – alec_djinn Jun 02 '17 at 11:23
  • Does `WhateverFunction` need to be a method of `first_class` at all ? NB : the way your snippet is indented, `WhateverFunction` is actually defined within `first_class.__init__` and as such is only accessible within `first_class.__init__` – bruno desthuilliers Jun 02 '17 at 11:24
  • @brunodesthuilliers ahh... Had put that down to a copy/paste or indentation error. But yes, that would change any possible answers somewhat – Jon Clements Jun 02 '17 at 11:33
  • You cannot have two instances of `tk.Tk` (or two instances of something that inherits from `tk.Tk`). Why must you have two classes that each inherit from `tk.Tk`? – Bryan Oakley Jun 02 '17 at 12:15
  • @BryanOakley That is the second part of the comment, but yes "you need to..." is not correct. – alec_djinn Jun 02 '17 at 12:16

3 Answers3

1

In your code you defined the function WhateverFunction as a local function within __init__. So it can't be seen from other sections of your code and it's impossible to be called.

Instead you can implement your function as a method, for example. It would look like this:

class first_class(tk.Tk):

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
             ....
    def WhateverFunction(self):
       "do sth"

Now the function can be called everywhere as a method of an instance of first_class:

first_class_instance = first_class()
first_class_instance.WhateverFunction()
Fomalhaut
  • 8,590
  • 8
  • 51
  • 95
  • Well no - leaving aside the lack of `self`, it'd still be callable via `first_class.WhateverFunction()`... it's not impossible to be called. – Jon Clements Jun 02 '17 at 11:29
  • @JonClements Look at the OP's code. `WhateverFunction` is local within `__init__`, so it can't be called, because it doesn't exist outside. – Fomalhaut Jun 02 '17 at 11:33
  • Yes... Just noticed... See my comment on the Q to Bruno. If it's deliberate then you are correct. – Jon Clements Jun 02 '17 at 11:34
0

I asked the exact same question on here a while back with no response. Basically, you can't do it. WhateverFunction only exists within the scope of __init__, which itself can only be called from second_class. This is done with the method described in the 'using methods from other classes' question you linked to, but it is useless for doing what you want to do because you may only get an output from __init__, and hence you can't access any functions defined within that function.

To work around this, why not define WhateverFunction globally and then call it as usual, or declare it outside of the __init__ function but still within first_class?

Sadie LaBounty
  • 379
  • 1
  • 5
  • 23
-1

Just create an instance of that class, and call the method if the second_class instance should be composed of the first one.

def second_class(tk.Tk):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        first_object = first_class().WhateverFunction()

Now a better approach would be to inherit second_class from the first one instead, and calling the method considering both classes have same parent, provided inheritance makes sense.

def second_class(first_class):

    def __init__(self, parent, controller):
        super(second_class, self).__init__(parent, controller)

        self.WhateverFunction()

Note:- please try to follow certain conventions of Python like naming classes with camel case, and methods/functions with snake case.

hspandher
  • 15,934
  • 2
  • 32
  • 45
  • inheritance is very probably not a "better approach"... Composition/delegation is usually a better choice, and actually plain functions or utility classes defined outside GUI classes are also a good way to share code without introducing undue dependencies. – bruno desthuilliers Jun 02 '17 at 11:27
  • What if the he's using the above class as just a mixin. I agree that's composition is often better than inheritance, but there are places where inheritance would make more sense. – hspandher Jun 02 '17 at 11:28
  • "there are places" indeed - I mean, there are _a few_ places where inheritance is the right solution. Only a few... Now we don't really have enough context to really say what's the "best" solution would be here since we don't know what `WhateverFunction()` does nor even if it really belongs in `first_class` to start with ;) – bruno desthuilliers Jun 02 '17 at 11:31
  • I agree we don't have enough knowledge to derive any adequate conclusion, but considering both of the classes are inheriting from `tk.Tk`, it's an educated guess that inheritance would be a better approach. – hspandher Jun 02 '17 at 11:33
  • The fact that two classes A and B have the same parent class P doesn't imply that A is a B in any way, specially when it comes to GUI or ORM classes. – bruno desthuilliers Jun 02 '17 at 11:38
  • That's why I had specially written that "provided inheritance makes sense". In the case you mentioned, it wouldn't. – hspandher Jun 02 '17 at 11:44