Trouble calling method from one class to another class

48 views
Skip to first unread message

RF

unread,
Apr 24, 2021, 1:01:44 PM4/24/21
to wxPython-users

I'm attaching my small demo test app. I'm having a heck of a time figuring out how to call add_tab_page() from the MyTreeCtrl class. This should happen when I just click on a tree node. While this doesn't seem to make any sense, what I plan to do with this action is open a new notebook tab and load in the filename into the new tab. But I have to get past this first: being able to call the add_tab_page() from the MyTreeCtrl class.

I'm fairly sure I'm missing something small here.

Thank you for any help.
pxCore2.zip

Dietmar Schwertberger

unread,
Apr 24, 2021, 1:41:15 PM4/24/21
to wxpytho...@googlegroups.com
When you want support, you should at least test the code before you post it.

Regards,

Dietmar

RF

unread,
Apr 24, 2021, 2:21:36 PM4/24/21
to wxpytho...@googlegroups.com
I did test it. I use PyCharm IDE and it runs fine (until I try to create a new tab page, then I get the error I'm trying to resolve).

What problem did you run into when you tried to start the app? I'm on windows 10. Perhaps you are running Linux or Mac? I have not tested on those OS's.

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/wxpython-users/8280ba78-37fb-e0a2-20f7-a9f4942eda0e%40schwertberger.de.


--
Ralph Freshour

Dietmar Schwertberger

unread,
Apr 24, 2021, 6:34:55 PM4/24/21
to wxpytho...@googlegroups.com
On 24.04.2021 20:21, RF wrote:
I did test it. I use PyCharm IDE and it runs fine (until I try to create a new tab page, then I get the error I'm trying to resolve).

It seems that your IDE does run something other than your programs.


pxCore.py tries to instantiate a control with a sizer as parent which does not work:

    self.tree = MyTreeCtrl(vbox, tID, size=wx.Size(240, 400), style=wx.TR_FULL_ROW_HIGHLIGHT | wx.TR_HAS_BUTTONS | wx.TR_NO_LINES)
  File "D:\Python\wxpython\bugs_etc\2021-04-24_Calling\pxCore.py", line 6, in __init__
    wx.TreeCtrl.__init__(self, parent, id, size, style)


pxCore2.py calls ...traverse_directory_tree... before self.tab_num is defined. This also does not work.
Even if this worked, you have a hard coded path which will fail on any machine except yours.

Regards,

Dietmar


john fabiani

unread,
Apr 24, 2021, 6:43:59 PM4/24/21
to wxpytho...@googlegroups.com

Take my advise with a smile because I am NOT the best programmer.  But, I have to say this is some very confusing code pxCore2.py.  I believe you do not have a handle on how OOP works within python. Also you copied code directly out of the wxPython demo but lacked the understanding of what was being presented.  And I bet this is causing confusion and is also not allowing you to move forward.

When you define a class, you don't normally create an instance of the class within the definition of the class.

self._MyTreeCtrl = MyTreeCtrl is in the __init__ method of MyTreeCtrl. 

so comment out "self._MyTreeCtrl = MyTreeCtrl"

I believe with wxPython 4.x the super() is used.

so

wx.TreeCtrl.__init__(self, parent, id, position, size, style)

is now

super().__init__(parent, id = id, pos= position, size = size, style=style)

You can review the what is needed to init wx.TreeCtrl by looking at the method in the source code.  In this case there are two signatures:

 TreeCtrl()

or  TreeCtrl(parent, id=ID_ANY, pos=DefaultPosition, size=DefaultSize, style=TR_DEFAULT_STYLE, validator=DefaultValidator, name=TreeCtrlNameStr)

Therefore, depending on your needs you could just use:

super().__init__()

At this point I stopped because the GUI opened and I'm not sure what you are trying to do.  If it is to list a directory there is a widget called 'FileDialog'.

Johnf

--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-user...@googlegroups.com.

RF

unread,
Apr 24, 2021, 6:54:09 PM4/24/21
to wxpytho...@googlegroups.com
> Even if this worked, you have a hard coded path which will fail on any machine except yours
Yes I am aware of that. I thought you would just edit the path so some files on your system would load into the tree. It doesn't matter what files are loaded since they are not being used yet.

Hmmm...I moved two TreeCtrl lines down below the add_tab_page() method call but it didn't make any difference. Please see the screenshot.

I'm also attaching the .py update file as pxCore3.py (in a zip file).

IDE Mod is the screen shot of my PyCharm IDE after I ran the updated file (showing the same error is still there).

Thank you...


--
You received this message because you are subscribed to the Google Groups "wxPython-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-user...@googlegroups.com.
IDE Mod.png
pxCore3.zip

RF

unread,
Apr 24, 2021, 7:32:55 PM4/24/21
to wxpytho...@googlegroups.com
John, thank you for those comments. I've looked at the __init__ docs and have adjusted accordingly.

One comment re the TreeCtrl __init__: I see in some examples I have looked at that they don't include all the parameters and their code runs without giving any errors. For example, this website: https://www.geeksforgeeks.org/wxpython-treectrl/

I don't understand why their codding example runs without error as they have omitted the style, validator and name. In any event, I followed your advice and patterned my __init__ after the options shown in the docs. However, I did make one exception: I omitted the TreeCtrl validator argument as I don't think I need it in the __init__. The line seems to execute OK without and I still am not sure it's optional as the __init__ docs show it in there. So I guess it is optional? Geeksforgeeks omitted three of the arguments and I didn't get any errors when I ran their example code.

I'm attaching pyCode4.py as the update with my changes (based on your comments).

> At this point I stopped because the GUI opened and I'm not sure what you are trying to d.
At this point, I am just trying to execute the file without getting the error: AttributeError: type object 'CoreFrame' has no attribute 'tab_num' on line 78.
Then I want to click on any tree node just to fire the add_tab_page() method and see that a new tab page is created.




--
Ralph Freshour
pxCore4.zip

john fabiani

unread,
Apr 24, 2021, 8:36:19 PM4/24/21
to wxpytho...@googlegroups.com

Python code has default values. In this case you don't have to pass any parameters to init the class for it to create an instance of the class.  Of course at some point those values will be needed.  That said, your code is needs the parameters:

super().__init__(parent, id = id, pos= position, size = size, style=style)

You are subclassing the wx.TreeCtrl class and you need to pass those parameters.  In the case of the Geeksforgeeks code they created an instance of the wx.TreeCtrl class directly (you could have also done the same).  They passed the parameters that were needed for their project and wxPython defaulted the rest.  BTW I'm not sure but I bet the underlining c++ code has multi-def of the code to allow passing all the parameters - all, some  or none.

The "tab_num" has some logic issues.  In the instance of the CoreFrame you create a var "self.tab_num" with the value of one (1).  But what is the name of the CoreFrame instance?  You named it "frame".  Therefore, any time you want to determine value of "tab_num" you would NOT use the following:

CoreFrame.tab_num

you would use

frame.tab_num.

Why"  Because the class name is CoreFrame and it is not the instance of the class.  The instance of the class is 'frame".

BTW in general I never do as you did above.  Adding the var and allowing it to increment within the instance will only apply to the one instance in this case "frame".  The moment you create a second instance of CoreFrame the value of "tab_num" will start over.  Of course maybe that is what you wanted.

Also in your "add_tab_page" method you set yourself to fail.  It only works the first time.  When you call from outside the instance there is no self.tab_num.

I'll let you think about how to fix that - there several ways!

Johnf

RF

unread,
Apr 25, 2021, 2:32:54 PM4/25/21
to wxPython-users
Thank you John for your comments. One at a time if I may.

> The "tab_num" has some logic issues ...

Well, I changed line 67: self.tab_num = 1
to
frame.tab_num = 1
and got: NameError: name 'frame' is not defined.

I'm thinking about this one...I must not have understood you correctly...the instance was created in line 95 and must not be 'global' since line 67 is complaining about it.

I'm attaching my current pyCore4.py file as pyCore4.2.py (zipped). Line 67 is the only change: frame.tab_num = 1
pxCore4.2.py.zip

john fabiani

unread,
Apr 25, 2021, 4:58:34 PM4/25/21
to wxpytho...@googlegroups.com

I guess I confused you.  The self.tab_num within the class constructor/def is just fine. Recall I would not do that.  I would have initialized a counter outside of my class.

CoreFrame is a class constructor or a definition of some object.  It is NOT the object!  You defined the var within the class constructor and it will work.  Therefore any instance of the class CoreFrame will contain the var tab_num and the start value is one (1).   The only instance of CoreFrame is named "frame" in your code.  'frame' is the object and it contains a var tab_num.  This happens when you do:

frame = CoreFrame()  frame is now an object as described by the class constructor CoreFrame.  You did that in "__main__".

An easy fix to your current code "tab_num" issue would be to use

 self.tab_num = 1 in the CoreFrame->__init__

and in your class MyTreeCtrl to use

frame.add_tab_page() and NOT CoreFrame.add_tab_page(CoreFrame) in the on_tree_single_click method.

Just because it is an easy fix does mean it is good code - I don't think it is.

Also make it easier for others to test your code by at least not hard coding a path to some file structure on your computer - maybe use os.getcwd()

Johnf

RF

unread,
Apr 25, 2021, 10:02:10 PM4/25/21
to wxPython-users
(1) I added os.getcwd()

(2) I modified self.tab_num per my understanding of your explanation.

(3) I added: frame.add_tab_page() but it gives the error: NameError: name 'frame' is not defined.
How would class MyTreeCtrl know about 'frame'? Do I have to pass it in as a parameter?

(4) zip file attached as v4.3

Thank you...
pxCore4.3.py.zip

john fabiani

unread,
Apr 25, 2021, 11:01:39 PM4/25/21
to wxpytho...@googlegroups.com

Does "frame.add_tab_page" require a passed parameter?  Before you read on please look at the method.


Hope you now realize your error?


If you still can't figure it out here is the answer:

you wrote:

frame.add_tab_page(self.tab_num)


should be

frame.add_tab_page()

I'm not sure why you are getting the error because you defined the instance "frame" in __main__.  That said, you are talking about scope.  You have designed the program that 'frame' is in the scope.  You need to read up on scope in python.

example:

def run():
  print(var)
if __name__ == '__main__':
   var = 'yes'
   run()

Johnf

john fabiani

unread,
Apr 25, 2021, 11:31:30 PM4/25/21
to wxpytho...@googlegroups.com

I decided to see why you are getting the error - so I ran the program on windows 10 python 3.8.  And sure enough the error appeared but it did not stop the program from running.  I'm going to make a wild guess and suggest that because the program is not structured well that is causing some issues with python on windows. The error does NOT appear on my Linux box.   That said, everything I said still applies.

Johnf

On 4/25/21 7:02 PM, RF wrote:

RF

unread,
Apr 26, 2021, 6:09:43 AM4/26/21
to wxPython-users
So if you can run the app (in Linux) without getting that 'frame' error, that must mean 'frame' is a global variable once it is created in __main__?

Thank you for all your help John. I've enrolled in Udemy for an OOP online course. I hope that will help me to better understand how to structure my app.
Reply all
Reply to author
Forward
0 new messages