Pergunta

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!

Foi útil?

Solução

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")]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top