Pygame Binding Menu items to functions (by clicking)

浪子不回头ぞ 提交于 2020-01-06 12:50:41

问题


Modifying the Squirrel Eat Squirrel Pygame for a class project. Trying to add in a menu, with basic Start, Quit and Settings buttons. I have the buttons there, and they will light up as the mouse scrolls over them. However, I can't figure out how to call their respective functions when I click on them. I am trying to call them by this:

def runMenu(self):
    mainloop = True
    while mainloop:

        self.__clock.tick(50)

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                mainloop == False
            if event.type == MOUSEBUTTONDOWN:
                for item in self.__items:
                    #print(item)
                    if item.isMouseSelecting(pygame.mouse.get_pos()):
                        print(self.__functions)
                        self.__functions[item]() #HERE <----

I believe it is because I am using a dictionary in my if name == "main" (See below) therefore it's not actually the dictionary, but its referencing its location? If that makes sense. (i'm not very good at explaining it, so sorry)

if __name__ == "__main__":
    screen = pygame.display.set_mode((640, 480), 0 , 32)

    menuItems = ('Start', 'Quit', 'Settings')
    functions = {'Start': main, 'Quit': terminate, 'Settings': None}

    pygame.display.set_caption('Main Menu')
    game = MainMenu(screen, functions, menuItems)
    game.runMenu()

The error it gives me in shell:

>>> ================================ RESTART ================================
>>> 
({'Start': <function main at 0x2969ab0>, 'Settings': None, 'Quit': <function terminate at 0x2969cf0>}, '#')
{'Start': <function main at 0x2969ab0>, 'Settings': None, 'Quit': <function terminate at 0x2969cf0>}

Traceback (most recent call last):
  File "/Users/tjleggz/Documents/CS 110/squirrel/squirrel.py", line 501, in <module>
    game.runMenu()
  File "/Users/tjleggz/Documents/CS 110/squirrel/squirrel.py", line 138, in runMenu
    self.__functions[item]() #cant call bc its not same object, just a ref to object or something???@
KeyError: <__main__.MenuItem object at 0x29758c8>
>>> 

THANKS!

EDIT:

class MenuItem(pygame.font.Font):
def __init__(self, text, font=None, fontSize=30,
             fontColor=(255, 255, 255), (posX, posY)=(0, 0)):
    pygame.font.Font.__init__(self, font, fontSize) #initializes font module
    self.__text = text
    self.__fontSize = fontSize
    self.__fontColor = fontColor
    self.label = self.render(self.__text, 1, self.__fontColor) #not private??
    self.width = self.label.get_rect().width
    self.height = self.label.get_rect().height
    self.__posX = posX
    self.__posY = posY
    self.position = posX, posY

def set_position(self, x, y):
    self.position = (x, y)
    self.__posX = x
    self.__posY = y

def isMouseSelecting(self, (posX, posY)): #change to conditional?!
    if (posX >= self.__posX and posX <= self.__posX + self.width) and \
    (posY >= self.__posY and posY <= self.__posY + self.height):
        return True
    else:
        return False

def setFontColor(self, rgbTuple):
    self.fontColor = rgbTuple
    self.label = self.render(self.__text, 1, self.fontColor)

回答1:


Your self.items contains MenuItem objects, not strings which are the keys to your dictionary. You can work around this in a couple ways, for example you could use the __text attribute of MenuItem which is I think what you are looking for.

A better way to do this (instead of using a dictionary of functions like you are now) might be to pass an on_click function to each MenuItem instance you make, and then you just have to write

if item.isMouseSelecting(pygame.mouse.get_pos()):
    item.on_click()

however you seem to be relatively new to programming, so you may just want to use the first suggestion.



来源:https://stackoverflow.com/questions/23505226/pygame-binding-menu-items-to-functions-by-clicking

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!