Home > OS >  Unable to modify value in _init_ function
Unable to modify value in _init_ function

Time:07-16

I'm making a Button class in python and I want to give a unique number to each button because when I will draw multiple buttons on pygame window, I will need to differentiate between these buttons using those unique numbers. The problem is I'm unable to modify the unique number (unq_number = 1 [Line 10 in code]). Python is giving me this error [local variable 'unq_number' referenced before assignment] but I have already defined the variable in the code (Line 4 in code).

import pygame

class Button:
    unq_number = 0

    def __init__(self, text, bg_color, width, height, pos, gui_font):
        self.pressed = False

        # unique number for each button
        unq_number  = 1
        self.unq_number = unq_number

        # Rectangle
        self.rect = pygame.Rect(pos, (width, height))
        self.bg_color = bg_color

        # text
        self.text_surf = gui_font.render(text, True, '#FFFFFF')
        self.text_rect = self.text_surf.get_rect(center=self.rect.center)

    def draw(self, surface, txt_color):
        pygame.draw.rect(surface, self.bg_color, self.rect)
        surface.blit(self.text_surf, self.text_rect)
        return self.check_click(txt_color)

    def check_click(self, txt_color):
        mouse_pos = pygame.mouse.get_pos()

        if self.rect.collidepoint(mouse_pos):
            self.bg_color = (0, 125, 110)

            if pygame.mouse.get_pressed()[0]:
                self.pressed = True
            else:
                if self.pressed == True:
                    self.pressed = False
                    return self.unq_number
        else:
            self.bg_color = txt_color

CodePudding user response:

self reference to this class here and you need to write self before your variable

import pygame

class Button:
    unq_number = 0

    def __init__(self, text, bg_color, width, height, pos, gui_font):
        self.pressed = False

        # unique number for each button
        self.unq_number  = 1
        #self.unq_number = unq_number

        # Rectangle
        self.rect = pygame.Rect(pos, (width, height))
        self.bg_color = bg_color

        # text
        self.text_surf = gui_font.render(text, True, '#FFFFFF')
        self.text_rect = self.text_surf.get_rect(center=self.rect.center)

    def draw(self, surface, txt_color):
        pygame.draw.rect(surface, self.bg_color, self.rect)
        surface.blit(self.text_surf, self.text_rect)
        return self.check_click(txt_color)

    def check_click(self, txt_color):
        mouse_pos = pygame.mouse.get_pos()

        if self.rect.collidepoint(mouse_pos):
            self.bg_color = (0, 125, 110)

            if pygame.mouse.get_pressed()[0]:
                self.pressed = True
            else:
                if self.pressed == True:
                    self.pressed = False
                    return self.unq_number
        else:
            self.bg_color = txt_color

CodePudding user response:

You must distinguish between the class attribute (see Class Objects) and the instance attribute (see Instance Objects). The class attribute is addressed with Button.unq_number and the instance attribute with self.unq_number.

minimal example

class Button:
    unq_number = 0

    def __init__(self):
        Button.unq_number  = 1
        self.unq_number = Button.unq_number

bl = []
for _ in range(4):
    bl.append(Button())
    print(f"{Button.unq_number} buttons: {[b.unq_number for b in bl]}")

output

1 buttons: [1]
2 buttons: [1, 2]
3 buttons: [1, 2, 3]
4 buttons: [1, 2, 3, 4]
  • Related