I'm developing some Raspberry Pi code - Python in Pygame - and I often want to view it's video-out in fullscreen mode. But since it's in dev, I often run into code errors that stop the Python program - printing the error-info in the Idle shell. But in fullscreen mode, even though the program has stopped, I haven't found a way to exit the screen to get back to Idle.
Anybody know a simple way?
I know I could probably be more defensive in catch-exception blocks, but I would think there's some non programatic way to exit after an error-stop.
It is a nice place to make use of the try--finally pattern -
If your code have an init function to enter fullscreen, and a main to actually run the game, it could go like that:
import pygame
...
def init():
global screen
screen = pyame.display.set_mode(...)
...
def main():
...
try:
init()
main()
finally:
pygame.quit()
Related
Need your help lads and lasses!
I made a very simple hangman game with a GUI in Tkinter and created a button event that calls the following function to restart the game. This works fine as a Python script but does not work when converting script to .exe with Pyinstaller. ('Window" here is the root Tkinter window)
def restart_func():
window.destroy()
os.startfile("main.py")
return
Any ideas why or alternative way of doing this would be much appreciated.
you should recreate your window and initialize it the same way you originially did.
def restart_func():
global window
window.destroy()
window = tk.Tk()
run_gui_initialization_function()
this is usually why some applications prefer OOP instead of functional programming, as there is usually no global state in OOP programming, while for functional programming, your run_gui_initialization_function should reinitialize all of your global state variables again.
an alternative way people do this is as follows
def main():
# do main app here
if __name__ == "__main__":
main()
this way you just need to run main() again after deleting your window if you ever need to restart your app.
Edit: okay, here's an easier to implement but too messy way to do this, you can start a detached version of your application from your executable ... but this is the wrong way to restart an application, and it might fail in some cases.
from subprocess import Popen
import sys
def restart_func():
window.destroy()
if getattr(sys, 'frozen', False) and hasattr(sys, '_MEIPASS'):
Popen(sys.executable,start_new_session=True) # if running as executable
else:
os.startfile("main.py") # if running as python script
I'm learning python with the book python crash course , i wrote the code for the game alien invasion , but it is not working , when i write "import sys" , the word sys is underscore and the program opens up the screen for like a millisecond and then it closes itself, i look for an answer in this site and YouTube and i haven't been able to find a solution, can anyone help? thanks in advance.
I'm using vs code on Linux mint.
this is what i wrote so far:
from settings import Settings
from ship import Ship
import sys
class AlienInvasion:
"""overall class to manage game assets and behavior"""
def __init__(self):
""" initialize the game and creates game resources"""
pygame.init()
self.settings = Settings()
self.screen = pygame.display.set_mode(
(self.settings.screen_width, self.settings.screen_height))
pygame.display.set_caption("Alien Invasion")
self.ship = Ship(self)
def run_game(self):
"""start the main loop for the game."""
while True:
self._check_events()
#whatch for keyboard and mouse events .
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
exit()
#redraw the screen during each pass through the loop.
self.screen.fill(self.settings.bg_color)
self.ship.blitme()
#make the most recently drawn screen visible.
pygame.display.flip()
if __name__ == '__main__':
#make a game instance, and run the game.
ai = AlienInvasion()
ai.run_game()
It looks like there's probably an error being thrown somewhere in your script that is causing the program to stop running, and as such, close the terminal as soon as it is opened. In my experience, this only happens when you execute the script from a file browser UI by double-clicking it.
To fix this, try running the program from somewhere that will stay open, even when the program is terminated, like, for example, the built-in terminal in vscode (you can reveal by going to view > terminal). To run the program, then simply run the command:
python path/to/my/script.py
If it causes an error, you will then be able to see it printed nicely, without the terminal closing.
On another note, importing sys has nothing to do with this problem. The reason it is highlighted by pylance is that you have imported it, but then you haven't used it anywhere (for example calling a function like sys.exit()), so it thinks that the line is unnecessary. It will go away once you use the sys module somewhere else in the script.
According to your error content, I think this is caused by the fact that the file is not found, meanwhile sys is not used in your code.
Here are some reasons caused "FileNotFoundError", you could confirm one by one:
1. File name and file type
The wrong file name was inserted into the code. Please carefully check the document name.
2. Escape of Python string
In the string of file, the address string information similar to C:\user\desktop will be involved, which conflicts with the escape function in Python string, such as \n representing line feed. Use r"C:\User\Desktop" or C:\\User\\Desktop to avoid Python escaping strings.
3. Relative path problem
Generally, it is not recommended to use. In the process of Python running, the relative path is the folder that the process points to when running, and the folder is used as the file tree of the root node, that is, if you open the file by using the relative path, you can only access the file under its root node.
You could use the methods os.path.abspath() and os.path.abspath('..') provided in the OS library to view and change the absolute path where Python runs.
4. Python runtime location
If it is such a problem, you can add the following code to the head of the file:
import sys
sys.path.append("../your/target/path/")
try pip install os-sys and pip install syspath
enter link description here
Gets error when I click the exit (X) button:
Failed to execute script pong
How can I close the turtle game by clicking the exit button with no error?
Getting errors from turtle when you close the window is highly indicative of not playing by the rules event-wise. Typically it's due to a while True: loop instead of using timer events. A properly event-drive turtle program should reach the mainloop statement (or one of its equivalents) and allow events to run the show. If you want specifics, provide your code as part of your question.
The error in the terminal must be due to the the while True: loop that most beginners like me use. Closing the window abruptly stops the process while the while True: loop was still going on. So, in order to avoid this error you can define a function
#Function
def quit():
global running
running = False
#Keybinding
screen.onkeypress(quit, "q")
#Main game loop
while running:
...
#update events
...
I'm building a headless soundboard using Raspberry Pi, and as such need a way to launch the script I'm using on boot. The program was edited and tested using the default editor Pi shot up, Thonny, and everything seems to run as intended. The buttons I'm using all play the sounds I expect them to, no issues.
I went ahead and edited rc.local to run the script as soon as the Pi boots (specifically, I added sudo python /filepath/soundboard.py & above exit 0), which it does. It seems to run identically to the way it did using Thonny, but sound cuts off after about 5 seconds, even if no buttons are pressed. When I run it directly through the command line, the same issue occurs.
The code here has been compressed, as there is more than one button, but they all use the same line.
import pygame
import random
import glob
from gpiozero import Button
import time
pygame.init()
while True:
n = glob.glob('/filepath/*.wav')
btn_0 = Button(8)
btn_0.when_pressed = pygame.mixer.stop
btn_0.when.held = lambda: pygame.mixer.Sound(random.choice(n)).play()
As far as I can tell, the while loop continues to run the program, but pressing buttons does nothing. Also, since adding the loop, the code dumps a Traceback, showing the error
gpiozero.exc.GPIOPinInUse: pin 8 is already in use by <gpiozero.Button objext on pin GPIO8, pull_up=True, is_active=False>
which might have something to do with my issue? btn_0 isn't the only button to have two functions assigned to it, but the only one to throw up this error, no matter what pin I use. The error doesn't appear if I remove the loop from the code.
You create btn_0 in an infinit while loop again and again. In the second iteration btn_0 is probably the first button that is created again. But pin 8 (which should be used for the button) has been assigned to the old instance of btn_0 in the last iteration.
You should move the glob.glob statement and the button initialization outside of the While loop. If the while loop is necessary to keep you program running place it below the initialization code and iterate over nop ore pause statements (whatever works).
If pygame.init starts it own looped thread you do not need a while loop at the end at all.
I don't know anything about pygame, so the last statement is just a guess.
Example:
import pygame
import random
import glob
from gpiozero import Button
import time
pygame.init()
n = glob.glob('/filepath/*.wav')
btn_0 = Button(8)
btn_0.when_pressed = pygame.mixer.stop
btn_0.when.held = lambda: pygame.mixer.Sound(random.choice(n)).play()
while True:
nop
I've written a mini example for DrawingArea which, when started, displays nothing. If I insert a raw_input() just for waiting for a keyboard press at a specific place, it functions, so this is a workaround. Here's the code:
#!/usr/bin/env python
import pygtk
pygtk.require('2.0')
import gtk
R = 300
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_default_size(R, R)
drawing_area = gtk.DrawingArea()
window.add(drawing_area)
window.show_all()
gc = drawing_area.get_style().fg_gc[gtk.STATE_NORMAL]
if 0:
raw_input()
drawing_area.window.draw_line(gc, R/10, R/10, R*9/10, R*9/10)
raw_input()
This version doesn't display the drawn line in the opening window; upon pressing enter in the shell, it will just terminate (and remove the window). But if I enable the raw_input() at the if 0: block, it waits twice for an enter in the shell and between the two enters it will display the drawn line (so in general the code works, it seems to be just a weird refresh problem).
I also tried to flush the event queue of GTK using this snippet:
while gtk.events_pending(): # drain the event pipe
gtk.main_iteration()
I inserted it at various places, always to no avail.
I also tried the usual gtk.main() as the last command in the script (of course). But it also didn't help.
How do I do this correctly and why is that raw_input() having that strange side-effect?
You should connect to your drawing area's expose-event signal. That is the only place that you should try to draw on the drawing area; the reason for this is that anything you draw is erased again when the window is minimized or another window moves over it. However, the expose event always happens at the right time so you can keep the drawing up-to-date whenever it is needed.
Like this:
def on_drawing_area_expose(drawing_area, event, data=None):
# ... do your drawing here ...
drawing_area.connect('expose-event', on_drawing_area_expose)
Also check out drawing with Cairo, which is the preferred and more flexible way. Here is a tutorial.