0

this is my current button code in Pygame with Python 3.

def button(text, posX, posY, width, height, inactiveColor, activeColor,action=None):
    mouse = pygame.mouse.get_pos()
    click = pygame.mouse.get_pressed()
    if posX + width > mouse[0] > posX and posY + height > mouse[1] > posY:
        pygame.draw.rect(displays, activeColor, (posX,posY, width, height))
        if click[0] == 1 and action!= None:
            action()
    else:
        pygame.draw.rect(displays,inactiveColor,(posX,posY,width,height))
    textSurf, textRect = text_objects(text, smallfont)
    textRect.center = ( (posX + (width/2)), (posY+(height/2)) )
    displays.blit(textSurf, textRect)

At the moment this has some problems, and I have tried searching this site but without a proper fix.

When the button is clicked, it will register nearly 20 function calls. I know this is because it is essentially running the function whilst the mouse button is held down, even if this is for only half a second.

I tried utilising MOUSEBUTTONDOWN but failed.

Additionally, I am trying to find out a way to have an 'action' (i.e. a function) run with arguments but only if arguments are given.

Finally, I am also trying to find a way to run an exec call as the 'action' so I can change a variable within the function call.

For example:

usernameRectangle = button("",200,195,500,30,GREY,BRIGHTGREY,exec('usernameActiveCheck = True')

At the moment, this is not possible.

I understand this is asking quite a lot, but I would appreciate any help.

Thank you!

Edit:

def button(text, posX, posY, width, height, inactiveColor, activeColor,action=None):
    mouse = pygame.mouse.get_pos()
    #click = pygame.mouse.get_pressed()
    click = pygame.MOUSEBUTTONDOWN
    if posX + width > mouse[0] > posX and posY + height > mouse[1] > posY:
        events = pygame.event.get()
        pygame.draw.rect(displays, activeColor, (posX,posY, width, height))
        hover = True
        while hover:
            for event in events:
                if event.type == click and action!= None:
                    hover = False
                    print("hover false")
                    action()
            if posX + width > mouse[0] > posX != posY + height > mouse[1] > posY:
                hover = False

Is code that I tried, but it didnt not work. It also had a wierd bug of triggering the action function without the button even being clicked

Second edit:

def button(text, posX, posY, width, height, inactiveColor, activeColor,action=None,actionArgs=None):
global buttonDown
mouse = pygame.mouse.get_pos()
click = pygame.mouse.get_pressed()
if posX + width > mouse[0] > posX and posY + height > mouse[1] > posY:
    pygame.draw.rect(displays, activeColor, (posX,posY, width, height))
    if click[0] == 1 and not buttonDown and action!= None:
        print("Clicked, button down and action")
        if actionArgs!=None:
            print("Actionargs")
            action(actionArgs)
        else:
            action()
        buttonDown = True
    elif click[0] == 0:
        buttonDown = False
else:
    pygame.draw.rect(displays,inactiveColor,(posX,posY,width,height))
textSurf, textRect = text_objects(text, smallfont)
textRect.center = ( (posX + (width/2)), (posY+(height/2)) )
displays.blit(textSurf, textRect)

Code now working thanks to comment responses and trying different things.

benjo456
  • 196
  • 1
  • 2
  • 10
  • Prefixing a variable with `*` will make a list, `**` will make dict. So you could use them in function declaration like `def foo( arg1, arg2, argn, *rest )`. `rest` will contain anything you passed after arg1-argn or will just be an empty list if you're not passing anything else. – Reaper Feb 13 '17 at 17:01
  • Also, what's more specificaly the problem with MOUSEBUTTONDOWN and what code have you tried with it? – Reaper Feb 13 '17 at 17:06
  • @Reaper thank you. Is it still possible to give 'action' a default value of None whilst doing this? – benjo456 Feb 13 '17 at 17:07
  • @Reaper original post updated with code – benjo456 Feb 13 '17 at 17:10
  • Yes, `def foo(arg1, argn, **rest)` should work. You can then use `somevar = rest.get('action', None)`. `somevar` will be `None` if no value for `action` was passed. – Reaper Feb 13 '17 at 17:13
  • Are you sure the very first `if` in updated code works as intended? More specificaly comparison operators. – Reaper Feb 13 '17 at 17:21
  • @Reaper could you please send me in the right direction? Really appreciate this help, thank you – benjo456 Feb 13 '17 at 17:59
  • Check the values returned by first and last `if` statements. In the last one you are comparing `boolean` values and that's probably why it's not working as intended. I'm not sure about `<>` since I can't check it atm. – Reaper Feb 13 '17 at 18:08
  • `hover = False` will only execute if `mouse[0]` is in range of (posX; posX + width) and `mouse[1]` is *not* in range of (posY; posY + height) or vise versa. Try `if not(posX + width > mouse[0] > posX and posY + height > mouse[1] > posY)` Btw, not related but do you see `@benjo456` prefix in my comments? – Reaper Feb 13 '17 at 18:16
  • @Reaper thanks, will try that now. And no, I do not. Do you see `@Reaper in my comments? – benjo456 Feb 13 '17 at 18:25
  • Yes, I do see it. Looks like that prefix in my comments gets deleted. I'll probably put it on meta. Thanks! – Reaper Feb 13 '17 at 18:30
  • @Reaper problem now fixed. Thank you so much! – benjo456 Feb 13 '17 at 20:42

0 Answers0