1

I know that something very basic is wrong here which I just fail to see. I'd really appreciate if somebody more experienced in Python could point out where I misunderstood things here. I post a simplified version of my code below. To trace back where the problems start, have an eye on the following:

The MainProgram, instanciated as Main = MainProgram(), has a menu (self.menu = Startmenu()) which is an instance of the Menu class. This Menu class has a list of buttons (self.buttons = [...]) - in this case only one. They are an instance of the Button class. I now need to pass the function to be triggered when the button is clicked to that instance of the Button class, so I can actually use it.

I would really be thankful to any more experienced user having a quick glance at it. I'm sure I'm failing to see something very basic. I bet I'm too tired to see it... Had only some 2 hours sleep since there's a baby in the house now :D

My code:

class MainProgram: #Much much more code def __init__(self): #And so much more code here self.menu = StartMenu() class StartMenu: def __init__(self): #Much code which is not important to us here self.buttons = [Button("d_bt_start", (100, 60) , testfunc, "TEST-TEXT")] class Button: def __init__(self, image, pos = (0, 0), path = Paths.path_img , alpha = False, func = None, args = None): self.img_normal = helper.loadImage(path, image + "_normal.jpg", alpha) self.img_hover = helper.loadImage(path, image + "_hover.jpg", alpha) self.image = self.img_normal self.pos = pos self.x = pos[0] self.y = pos[1] self.width = self.x + self.image.get_width() self.height = self.y + self.image.get_height() self.mouseover = 0 self.func = func self.args = args def update(self, (mx, my)): if (mx >= self.x and mx <= self.width and my >= self.y and my <= self.height): if self.mouseover == 0: self.image = self.img_hover self.mouseover = 1 else: if self.mouseover == 1: self.image = self.img_normal self.mouseover = 0 def clicked(self, button): if (mx >= self.x and mx <= self.width and my >= self.y and my <= self.height): if button == 1: self.func(self.args) 

What should happen: The main file creates an instance of the StartMenu class. In the StartMenu class we define one button as an instance of the Button class. That button should trigger the function testfunc(args) upon being clicked. This testfunction is so far just a print of the "TEST-TEXT" argument.

If I pass the function as

testfunc 

then I get the following error Traceback:

Traceback (most recent call last): File "D:\Python27\_RPG DEMO\DEMO\main.py", line 41, in <module> Main = MainProgram() File "D:\Python27\_RPG DEMO\DEMO\main.py", line 21, in __init__ self.menu = menus.StartMenu() File "D:\Python27\_RPG DEMO\DEMO\menus.py", line 11, in __init__ , zztestfile.testfunc, "TESTEST") File "D:\Python27\_RPG DEMO\DEMO\buttons.py", line 7, in __init__ self.img_normal = helper.loadImage(path, image + "_normal.jpg", alpha) File "D:\Python27\_RPG DEMO\DEMO\helper.py", line 13, in loadImage return pygame.image.load(os.path.join(folder, name)).convert_alpha() File "D:\Python27\lib\ntpath.py", line 96, in join assert len(path) > 0 TypeError: object of type 'function' has no len() 

If I pass it as:

testfunc("TEST-TEXT") 

it triggers but then causes the following Traceback:

TEST-TEXT Traceback (most recent call last): File "D:\Python27\_RPG DEMO\DEMO\main.py", line 41, in <module> Main = MainProgram() File "D:\Python27\_RPG DEMO\DEMO\main.py", line 21, in __init__ self.menu = menus.StartMenu() File "D:\Python27\_RPG DEMO\DEMO\menus.py", line 11, in __init__ , testfunc("TEST-TEXT")) File "D:\Python27\_RPG DEMO\DEMO\buttons.py", line 7, in __init__ self.img_normal = helper.loadImage(path, image + "_normal.jpg", alpha) File "D:\Python27\_RPG DEMO\DEMO\helper.py", line 15, in loadImage return pygame.image.load(os.path.join(folder, name)).convert() File "D:\Python27\lib\ntpath.py", line 96, in join assert len(path) > 0 TypeError: object of type 'NoneType' has no len() 

I've gone through a few tutorials so far, but I really can't figure out where I'm misunderstanding them. I'd really appreciate any help in this!

4
  • This doesn't answer your question, but Python 2 classes should aways inherit from object; using old-style classes in new code is a Bad Idea. Commented Apr 16, 2014 at 10:27
  • @MartijnPieters: It's an external function (from another module) which loads images and converts them for pygame. Since it's not relevant to the question I didn't explain anything about it here, but if you're interested we can discuss it as well. Commented Apr 16, 2014 at 18:33
  • @Wooble: Thank you for your comment. I'm really desperately searching for more in-depth information about such things as it seems that tutorials always take it for granted that people already know it :/ So I'd really appreciate any information you can provide, I'm keen to learn better :D Commented Apr 16, 2014 at 18:34
  • @PatricHartmann: No, it was a red herring; I was trying to figure out how you managed to pass a function through to the os.path.join() function before I realized what was going wrong. Commented Apr 16, 2014 at 18:36

1 Answer 1

3

You are passing your test function to the path argument of your Button class:

self.buttons = [Button("d_bt_start", (100, 60) , testfunc, "TEST-TEXT")] 

That's the 3rd positional argument there:

def __init__(self, image, pos = (0, 0), path = Paths.path_img , alpha = False, func = None, args = None): 

matching up with path. Use keyword arguments instead:

self.buttons = [Button("d_bt_start", (100, 60) , func=testfunc, args="TEST-TEXT")] 
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much! In German we have a proverb, that there are so many trees that you don't see the forest anymore... That's what happened to me and you guided me the right way.
The same proverb works in English too (though I do know it in Dutch and German as well) :-) Not seeing the forest for the trees.
That's interesting to know, I'm quite into linguistics :D Another hobby of mine that gets much less attention than it deserves... By the way: it perfectly works now... It's embarassing, I have to admit, to make such a mistake and not finding it... :D

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.