Pygame program stops responding, giving no error

2019-07-26 11:06发布

问题:

so my program is meant to display buttons in rows, then wait for the user to click one, however what would happen is that the it would return to the main menu.

I was unsure of how to make the program wait ( I tried time.sleep() and os.system("pause"), however both of these would just wait for a certain amount of time and then also return to the main menu - so I resorted to using a console input, just to see if the boxes were being correctly displayed.

However now with the console input, clicking on any of the buttons makes the program not respond (when the button should be changing color) - I've included a screenshot. Program not responding

I was wondering what I'm doing wrong, I understand this is sort of a mess, I'd be really happy for some sort of response and I can provide more information if needed. Many thanks.

This is the code for displaying the buttons.

screen.fill(white) #clear the screen
xPos = -135;yPos = 200;tasktodo = "null" #set the position of where the first buttons should be placed
for i in tasklist[posInList][2]: #For each task the user has been set
    for y in QuestionTypes: #For each item in QuestionTypes ([MPQ,DBQ,RatioQ]...)
        if str(y) in str(i): #If the any item in QuestionTypes is in the tasks the user is set:
            task = (i.split(",")[0]) #This splits up the various tasks to the form of [DBQ,MPQ,AFQ]

            if xPos > display_height: #If the place a button would be placed is out of bounds
                xPos = 50 #Reset xPos
                yPos += yPos -82 #Lower the position of the button to another row
            else:
                xPos += 185 #Else, place the button 185 pixels to the right
            button(str(task), xPos, yPos, 150, 90, grey, lightGrey, action=str(task)) #Place a button with the name of the task, in position (xPos,yPos), dimensions (150,90),active/inactive colors of grey/light grey action being the task

            listOfSetQuestions.append(y) #Append the tasks the user has to do to a list
            amountoftasks += 1 #Keep track of the amount of tasks the user has to do.
# After the tasks are all printed, the user must input what task they wish to do
message_to_screen("These are the tasks your teacher has set, pick one:", black, "medium", -200) #send a message to the screen, black color, medium size font and y position of -200
pygame.display.update()

x = input("press ENTER to continue")

This is the code for the button, so you can see it for more context.

def button(text, x, y, width, height, inactiveColor, activeColor, action = None):
cur = pygame.mouse.get_pos() #Gets the position of the cursor
click = pygame.mouse.get_pressed() #will return a tuple of 3, click[0] is left click, click[1] is middle and click[2] is right.
if x + width > cur[0] > x and y + height > cur[1] > y: #If the mouse is clicked and is between the borders of the button.
    pygame.draw.rect(screen, activeColor, (x,y,width,height)) #Change the color of the button to the active color, to show it is clicked
    if click[0] == 1 and action != None: #if the mouse is clicked, and there is a purpose to the click (clicked on a button)
            if action == "Create":
                Create()
            if action == "Sign in":
                Sign_In()
            if action == "Teacher":
                pass
            if action in QuestionTypes:
                print (action)
                global tasktodo
                tasktodo = action

else:
    pygame.draw.rect(screen, inactiveColor, (x,y,width,height))

text_to_button(text,black,x,y,width,height)

回答1:

When asking for input the program stops and wait until the user types something in. When the program stops it cannot handle events which makes your os to believe the program has crashed. So when using pygame you cannot have console input (unless you create processes).

If all you needed was a delay, you could use a while-loop

def wait(time):
    clock = pygame.time.Clock()

    while time > 0:
        dt = clock.tick(30) / 1000  # Takes the time between each loop and convert to seconds.
        time -= dt
        pygame.event.pump()  # Let's pygame handle internal actions so the os don't think it has crashed.

If you want the user to decide how long to wait, you could check for user events

def wait_user_response():
    clock = pygame.time.Clock()
    waiting = True

    while waiting:
        clock.tick(30)

        for event in pygame.event.get():
            if event.type == pygame.KEYDOWN:  # Or whatever event you're waiting for.    
                waiting = False

There are of course other better ways to go about, but since I don't know how your program functions, this was all I could provide.



标签: python pygame