Pygame - "error: display Surface quit" - python-2.7

I've made a menu screen where clicking on a button leads to a different screen in the same window.
def main():
import pygame, random, time
pygame.init()
size=[800, 600]
screen=pygame.display.set_mode(size)
pygame.display.set_caption("Game")
done=False
clock=pygame.time.Clock()
while done==False:
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
done=True
break
if button_VIEW.collidepoint(pos):
if event.type == pygame.MOUSEBUTTONDOWN:
print("VIEW.")
view()
break
screen.fill(black)
...
def view():
done=False
clock=pygame.time.Clock()
while done==False:
for event in pygame.event.get():
pos = pygame.mouse.get_pos()
if event.type == pygame.QUIT:
done=True
break
...
If possible, I'd like to know how I can avoid the error:
screen.fill(black)
error: display Surface quit
>>>
After looking at other questions on here, I tried adding breaks to the exits of any loops, but still the error occurs.
I understand the issue is that the program is trying to execute screen.fill(black) after the window has been closed, but I have no further ideas on how to prevent the error.
I appreciate any help. Sorry if it seems simple.

Several possibilities:
end the process (with e.g. sys.exit()) in the view function. Not ideal.
return a value from the view function to indicate that the application shoud end (e.g. return done), and check for that return value in the main function (if done: return). Better.
make done global and check for its value in the main function. I really would not like this solution.
my favourite: avoid multiple event loops altogether, so the problem solves itself (so you could just e.g. exit the main function with return).

Related

how to record button presses in python to open combination lock

Im trying to use my raspberry pi to play sounds when buttons are pushed and additionally output when the right order of button presses are made.
i've figured out the sounds pretty good and got that working but cant figure out how to program the combination lock. Any help would be appreciated to get me on the right path. (output would be setup as 26)
code thus far:
import os
from time import sleep
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(17, GPIO.IN)
GPIO.setup(27, GPIO.IN)
GPIO.setup(22, GPIO.IN)
GPIO.setup(10, GPIO.IN)
while True:
if (GPIO.input(17) == False):
os.system('mpg123 /home/pi/frogjars/frog1.mp3 &')
print("Button 1 Pressed")
sleep(3)
if (GPIO.input(27) == False):
os.system('mpg123 /home/pi/frogjars/frog2.mp3 &')
print("Button 2 Pressed")
sleep(3)
if (GPIO.input(22) == False):
os.system('mpg123 /home/pi/frogjars/frog3.mp3 &')
print("Button 3 Pressed")
sleep(3)
if (GPIO.input(10) == False):
os.system('mpg123 /home/pi/frogjars/frog4.mp3 &')
print("Button 4 Pressed")
sleep(3)
sleep(0.1);
This is going to depend on how you want to handle entry of the combination. The simplest/crudest method is to append each button press to a string and then check if the combination is in the string. Clearing the cached button presses after a timeout, or a number of presses, will require a little more complexity.

Please fix my function ive tried everything but i cant get my while loop to end when the function is over

When i run this and type start it doesnt stop and return back to the console
#this code defines the menu:
def main():
print('this will be the main menu')
return(Menu == False)
#this was temporary code to prevent the menu from launching on start up this function will soon be used to start other functions from the 'console' onces i add a dictionary of functions
Menu = False
def Mcall(x):
Menu = True
while Menu == True:
Menu = main()
#this code is a console or menu that should start functions or end the program
while(True):
CP = raw_input("enter a comand:\n")
if CP == 'start':
Mcall('start')
Figgued it out!
I was trying to end the while loop while inside a function with Menu = False when it needed to be under the function on the loop's indentation. Why it doesent work this way im not sure but I bet it has something to do with global variables not being changed within a function.

pygame can't proceed successfully

import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((600,170),0,32)
pygame.display.set_caption("Hello World!") //set caption
background = pygame.image.load('bg.jpeg').convert //load picture and convert it
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.blit(background,(0,0))
pygame.display.update() //refresh
The Error I get :
File "/Users/huangweijun/PycharmProjects/untitled1/first.py", line 12, in<module>
screen.blit(background,(0,0))
TypeError: argument 1 must be pygame.Surface, not builtin_function_or_method
i have download pygame
i don't know how to solve this issue.
The first argument of the function screen.blit is a pygame Surface. Think of this as a screen to draw to. You are specifying an object of the class Image. This will not work for you cannot draw to an image.
Replace background with screen and add background as an argument between screen and (0,0). You code should now look like this:
import pygame
from sys import exit
pygame.init()
screen = pygame.display.set_mode((600,170),0,32)
pygame.display.set_caption("Hello World!") //set caption
background = pygame.image.load('bg.jpeg').convert //load picture and convert it
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
screen.blit(screen,background,(0,0))
pygame.display.update() //refresh
pineapple, Looks like the issue here is in this line:
background = pygame.image.load('bg.jpeg').convert
I think what you wanted to use was:
background = pygame.image.load('bg.jpeg').convert_alpha()
Hopefully that's what you were looking for!
EDIT: You could have also just added parentheses after the convert() Oops!
Try them both and see what happens!
-Travis

Why does gtk.main_quit() not work?

I'm new here. :)
I am having trouble emigrating from GTK+ in C to PyGTK, specifically I do not understand why (in this specific context of a pause/play button) gtk.main_quit() does nothing even though it is called.
In my working example, after you press "Play", press "Pause" and then try to use the "Quit" button. On my end the "Quit" button, even though it calls gtk.main_quit() (and prints stuff after it to prove it does), will not have any effect on the program. Any ideas on what I am doing wrong?
Here it is:
import pygtk
pygtk.require('2.0')
import gtk, gobject, cairo
import time
global paused
paused = False
running = False
def some_stuff(widget, data=None):
global paused
global running
x = 0
if running:
return
running = True
paused = False
while True:
x += 1
print x
while gtk.events_pending():
gtk.main_iteration(False)
while paused:
while gtk.events_pending():
gtk.main_iteration(False)
running = False
paused = False
def pause_stuff(widget, data=None):
global paused
paused = not paused
def force_quit(widget, data=None):
print 'before'
gtk.main_quit() # doesn't work, gtk main loop keeps running
#exit() # obviously works to kill everything
print 'after'
def main():
window = gtk.Window()
window.connect("delete-event", force_quit)
window.show()
vbox = gtk.VBox(True, 3)
vbox.show()
window.add(vbox)
button = gtk.Button("Play")
button.connect("clicked", some_stuff, None)
vbox.add(button)
button.show()
button = gtk.Button("Pause")
button.connect("clicked", pause_stuff, None)
vbox.add(button)
button.show()
button = gtk.Button("Quit")
button.connect("clicked", force_quit, None)
vbox.add(button)
button.show()
window.present()
gtk.main()
return 0
if __name__ =="__main__":
main()
gtk.main_quit() instructs the GTK main loop to terminate. It has no effect in your code because your some_stuff() function implements its own version of the main loop, unaffected by calls to gtk.main_quit(). Since the outer while never exits, once the Play button is clicked, you never return into the real GTK main loop.
A correct GTK program does not reimplement the main loop like some_stuff() does, precisely to avoid such problems, and also to avoid busy-looping while nothing is going on. The while gtk.events_pending(): gtk.main_iteration() idiom should be used very sparingly, only when absolutely necessary (updating a progress bar comes to mind).
Adding this as answer based on the comment to the other answer (since this is a bit long for a comment). Let's assume that one game iteration is fast and you can do one in gtk main thread without hurting the UI.
Make a function that runs one single iteration of your game (to begin with you can just print something). The function should be an "idle handler callback" (see below). It should return True, except if the game is paused or stopped: in that case it should return False (meaning the function should not be called again).
In Play() add an idle handler for the iteration function
In Pause(), update the paused variable, and if unpausing also add an idle handler like in Play()
This way the iteration function keeps getting called after Play is called (but the UI is also updated). after Pause the iteration function is still called once, but it will return False and will not be called again.

Pygame - pygame.mouse.get_pos problems

The problem isn't errors, it's just that i'm trying to get this crosshair image to follow the mouse about the screen, I succeeded but it's leaving a trail of the same image behind it so the screen eventually becomes spammed with the image, heres the code:
import sys, pygame;
from pygame.locals import *;
spaceship = ('spaceship.png')
mouse_c = ('crosshair.png')
pygame.init()
screen = pygame.display.set_mode((800, 600))
mousec = pygame.image.load(mouse_c).convert_alpha()
space_ship = pygame.image.load(spaceship).convert_alpha()
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
sys.exit()
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
print("test1")
elif event.type == MOUSEBUTTONDOWN and event.button == 3:
print("test3")
pos = pygame.mouse.get_pos() #Here is the mouse following code
screen.blit(mousec, (pos)) #Setting image to pos of mouse.. atleast I think I am
pygame.display.update()
Your code has no problem....it is doing what you are telling it.
However for any image drawn a new background is created (along with the image) that is set as the new background it self so the background needs to be erased and set to default before the function pygame.display.update() or pygame.display.flip() is called.
more information here
So basically all you can do is create a new background by taking a image (800x600) ('background.png').
Load it:
bk = pygame.image.load('background.png').convert_alpha()
Blit it before blitting other moving objects.screen.blit(bk, (0,0))pos = pygame.mouse.get_pos() #Here is the mouse following code
screen.blit(mousec, (pos)) #Setting image to pos of mouse
pygame.display.update()
Adding a background to your game provides the game a complete touch but if you do not want to add it then the simplest thing you can do is fill your screen with a color every time the while loop is called.
So just after the while loop starts add this:
screen.fill(Color("black"))