2

like the title says, I want to shorten this:

while run:
        global mouse
        mouse = pygame.mouse.get_pos()

        first_button = button(pic, .1, .1, .1, .1)
        second_button = button(pic, .25, .1, .1, .1)
        third_button = button(pic, .75, .1, .1, .1)
        first_button.drawButton()
        second_button.drawButton()
        third_button.drawButton()

to somthing like this:

while run:
        global mouse
        mouse = pygame.mouse.get_pos()

        first_button = button(pic, .1, .1, .1, .1)
        second_button = button(pic, .25, .1, .1, .1)
        third_button = button(pic, .75, .1, .1, .1)
        button.drawButton()

but when I do that, it says " drawButton() missing 1 required positional argument: 'self' "......... for reference, this is my button class:

class button:
    global uiX, uiY, uiW, uiH
    def __init__(self, image, x, y, w, h):
        self.image = image
        self.bx = int(uiX + (x * uiW))
        self.by = int(uiY + (y * uiH))
        self.bw = int(w * uiW)
        self.bh = int(h * uiH)

    def drawButton(self):
        pic = pygame.transform.scale(self.image, (self.bw, self.bh))
        win.blit(pic, (self.bx, self.by))
        if ((self.bx < mouse[0] < (self.bx + self.bw)) and (self.by < mouse[1] < (self.by + self.bh))):
            pygame.draw.rect(win, (0, 0, 0,), (self.bx, self.by, self.bw, self.bh))

    def click(self):
        if ((self.bx < mouse[0] < (self.bx + self.bw)) and (self.by < mouse[1] < (self.by + self.bh))):
            print("Whatever the function will be")
  • you need to keep track of the instances yourself, probably using some container like a `list` or a `dict` or whatever you need – juanpa.arrivillaga Oct 18 '19 at 07:25
  • Rabbid76 already gave you the answer, maybe you can make use of this [answer](https://stackoverflow.com/questions/57557599/why-wont-my-button-change-color-when-i-hover-over-it-pygame/57558056#57558056). It contains a button class that makes use of some pygame features like Rect, Sprite and Group. – sloth Oct 18 '19 at 07:27

2 Answers2

4

That is the wrong way. A class doesn't know all its instances.

Create a list of buttons (before the main loop):

buttons = [
    button(pic, .1, .1, .1, .1)
    button(pic, .25, .1, .1, .1)
    button(pic, .75, .1, .1, .1)
]

Draw the buttons in a for loop:

while run:
    global mouse
    mouse = pygame.mouse.get_pos()

    for b in buttons:
        b.drawButton()
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
1

You can use a class method to "register" every instance. I do not know if this is recommended or not

Here's a minimal example:

class Test:
    instances = []

    @classmethod
    def addInstance(cls, instance):
        cls.instances.append(instance)

    @classmethod
    def getInstances(cls):
        return cls.instances

    def __init__(self, arg):
        self.arg = arg
        self.__class__.instances.append(self)


a = Test("Hello")
b = Test("Hellu")
c = Test("Helli")

for instance in Test.getInstances():
    print(instance.arg)

Hope that helps.

Remi
  • 11
  • 1