Willi
Willi

Reputation: 33

I cannot get a class method working; if I copy-paste the method code where the method should be called, it works

I'm relatively new at programming my own classes in Python. I work on a program in which I have already defined 3 classes with 4/5 methods each which are perfectly working. But I'm encountering a problem with a new one for an hour and I can't figure out what I am doing wrong. In fact, the method doesn't work even though there are not a error message that pops up, but if I copy-paste the code of the method in my pygame loop (where it is called), it works perfectly fine. Here's the code of my class (the .click(self) method being the one at stake here):

class button:
    def __init__(self, window, xpos, ypos, width, height, color = white, text = '', dest = None):
        self.xpos = xpos * r
        self.ypos = ypos * r
        self.width = width * r
        self.height = height * r
        self.color = color
        self.colorBuffer = [color[i] for i in range(3)]
        self.window = window
        self.hovered = False
        self.clicked = False
        self.text = text
        self.dest = dest
        #self.R = color[0]
        #self.G = color[1]
        #self.B = color[2]
    
    def click(self):
        self.clicked = True
        if self.dest == None:
            pass
        else:
            currentMenu = self.dest
            self.dest.disp()
            self.clicked = False

Here's the code where the method is called (it's called when the program checks if event.type == MOUSEBUTTONDOWN):

loop = False
if loop == False:
    currentMenu = mainMenu
loop = True
boxisinputting = False
boxinputting = None
userisinputting = False

while loop == True:
    pygame.display.flip()
    userisinputting = False
    mousex, mousey = pygame.mouse.get_pos()
    currentMenu.disp()
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            loop = False
            pygame.quit()
        if event.type == pygame.KEYDOWN:
            if pygame.key.name(event.key) == 'return':
                boxinputting.inputting = False
                boxisinputting = False
        if event.type == pygame.MOUSEBUTTONDOWN:
            if event.button == 1:
                for but in currentMenu.buttonList:
                    if but.hovered == True:
                        but.click()
                if boxisinputting == False:
                    for box in currentMenu.inputBoxList:
                        if box.hovered == True:
                            box.inputting = True
                            boxisinputting = True
                            boxinputting = box
    if userisinputting == True:
        boxinputting.render()
    pygame.time.delay(100)

What happens when I run this code: The next menu displays fine, but its buttons aren't responding (I have methods that light it up or down whether the mouse in on the button); instead, it is the buttons of the previous menu that pop up when I move my pointer where they were. However, when I copy-paste the instructions I want my method .click(self) to do here:

if event.type == pygame.MOUSEBUTTONDOWN:
    if event.button == 1:
        for but in currentMenu.buttonList:
            if but.hovered == True:
                but.clicked = True
                if but.dest == None:
                    pass
                else:
                    currentMenu = None
                    currentMenu = but.dest
                    but.dest.disp()
                    but.clicked = False

... well, it works perfectly fine: the buttons are active and responding, and the previous ones don't pop up out of nowhere (which is what I'm willing to do). I could get away with it, because this would just waste 5 ou 6 lines in my loop. But I'm interested in knowing why I can't get the method working, in order to avoid future issues like this one.

Thank you for reading my post!

William

Upvotes: 3

Views: 74

Answers (1)

Kingsley
Kingsley

Reputation: 14906

It's hard to tell, because the included code does not show the instantiation of a button, but probably you need to ensure it's referencing the global scope:

def click(self):
    global currentMenu, gamesMenu
    currentMenu = gamesMenu
    print('click')

Your button class would be better if it would just stick to being only a button. So that's about the location, and the label, colours, whether it's clicked, unclicked, hovered, etc. But what it is not is also important. A button is not a menu, it shouldn't know about menus, and it shouldn't handle menus (or flush the display buffer!).

Objects produce better designs and cleaner code when they're concise about what they do.

Upvotes: 2

Related Questions