I am doing a Photobooth with printing (and uploading) option.
This project presents itself like this:
Start screen with instructions --> preview results screen --> user chooses either to print or restart (or the timeout chooses restart for the user)
If the user chooses print then, printing is done, and a message is displayed (sleep method) before going back to the start screen.
Now, i have one main issue:
Getting back to the start screen...
The simplified code is here:
def PreviewMontage(MontageFile):
global LastTap
LastTap = time.time()
print("Session ID:", SessionID)
print("Show something.")
preview = pygame.image.load(MontageFile)
PILpreview = Image.open(MontageFile)
previewSize = PILpreview.size # returns (width, height) tuple
#added /1.5
ScaleW = AspectRatioCalc(previewSize[0]/1.5, previewSize[1]/1.5, SCREEN_HEIGHT)
preview = pygame.transform.scale(preview, (ScaleW, SCREEN_HEIGHT))
SetBlankScreen()
background.blit(preview, (SCREEN_WIDTH/2-ScaleW/2, 0))
PrintScreen()
#inserting conditions here - get mouse
camera.stop_preview()
UpdateDisplay()
Wait()
return
def Wait():
clock = pygame.time.Clock()
waiting = True
while waiting:
time = 60
time = time -1
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN and event.button == LEFTMOUSEBUTTON:
x, y = event.pos
print("You pressed the left mouse button at (%d, %d)" % event.pos)
LeftMouseButtonDown(x, y)
if time == 0:
waiting = False
return
I encounter the problem of getting back to the main screen, it seems that the Wait() function never ends...
You are setting the time to 59 on every iteration of your while loop. It means time never reaches 0 and the loop is infinite.
Fix it by declaring time = 60 outside the while()
Related
I want to write a bot that will simulate mouse movements when user is away for more than 5 minutes and stay put when user takes control i.e. moves the mouse.
I have written following code as a part of the program.
Here is the link to my old program which clicks at given points periodically. The problem with this program is I have to start the program when I want to go somewhere and after returning close the program in order to resume working.
Here is the one of the module I wrote for the new program which detects whether mouse is moving or not.
import win32api
from time import sleep
print("starting engine.")
count = 0
while(True):
savedpos = win32api.GetCursorPos()
if count>20*5:
break
sleep(1)
curpos = win32api.GetCursorPos()
if savedpos == curpos:
savedpos = curpos
print("Mouse is steady.")
else:
print("Mouse is moving.")
count += 1
I wont be writing the code but I have the Idea to solve the problem
you use pyautogui.position() to keep checking the position and if it doesnt change position for 300 seconds you move it
I wrote following code referring other Stackoverflow posts.
This code waits 4 minutes for mouse being steady. Whenever mouse is moved, timer is reset to zero.
import win32api
from time import sleep
import pyautogui as gui
print("starting engine.")
count = 0
savedpos = win32api.GetCursorPos()
def actions():
print(gui.size())
while True:
#toast.show_toast("ROBOT V2 !", "Robot is active.", threaded=False, icon_path=None, duration=2)
gui.click()
gui.press('home')
gui.moveTo(541, 142, 0.25) # Money Transfer dropdown
gui.click()
sleep(0.5)
gui.moveTo(541, 172, 0.25) # Money Transfer link
gui.click()
sleep(5)
cond()
def cond():
count = 0
while True:
savedpos = win32api.GetCursorPos()
sleep(0.5)
curpos = win32api.GetCursorPos()
if savedpos == curpos:
savedpos = curpos
print("Mouse is steady. Elapsed time: ", (count+1)/2, " seconds.")
count += 1
if count >= 480: # if count is greater than 60 it means timeout will occur after mouse is steady for more than
# 240 seconds i.e. 4 minutes. (approx.)
print("User away for more than 4 minutes, taking control of the system.")
actions()
break
else:
pass
else:
print("Mouse is moving.")
count = 0
cond()
I have some python code on a raspberry pi that I want to run and carry on a loop until a button is pressed.
The button.wait_for_press() is not suitable because that pauses the program until it runs, but I have tried it out to see if the hardware is working and it does.
def shutterPressed():
global shutterHasBeenPressed
shutterHasBeenPressed = True
def main():
"""
Main program loop
"""
#start camera preview
camera.start_preview(resolution=(SCREEN_W, SCREEN_H))
#Display Intro screens
intro_image_1 = REAL_PATH + '/assets/intro_1.png'
intro_image_2 = REAL_PATH + '/assets/intro_2.png'
overlay_1 = overlay_image(intro_image_1, 0, 3)
overlay_2 = overlay_image(intro_image_2, 0, 4)
#Wait for button press
i = 0
blink_speed = 10
button.when_pressed = shutterPressed
while True:
global shutterHasBeenPressed
shutterHasBeenPressed = False
#Stay in loop until button is pressed
if shutterHasBeenPressed is False:
i += 1
if i == blink_speed:
overlay_2.alpha = 255
elif i == (2 * blink_speed):
overlay_2.alpha = 0
i = 0
#Restart while loop
sleep(0.1)
continue
#button has been pressed!
print("Button Pressed!")
When I run this code, the button press is not registered at all.
What have I got wrong?
EDIT: so I added a print statement to the shutterPressed() function and confirmed that it is running when the button is pressed.
In also added a statement to print the value of shutterHasBeenPressed just before the if statement. This never changed from false.
However, if I removed the line changing the variable to false at the beginning of the loop, then code worked, so it is obviously something to do with when various bits get run. Maybe the while loop starts again after the shutterPressed() function runs?
Either way, i have fixed it by moving the reassignment of the variable to after the if statement.
Welcome to the world of concurrency (somewhat)!
Just imagine your program running: the instructions are being executed one after the other in the order in which they are written, according to the execution flow that they define with the exception of shutterPressed which is asynchronously executed (maybe).
Therefore, imagine we enter the loop and are at the first line, <here>:
while True:
global shutterHasBeenPressed
shutterHasBeenPressed = False # <here>
#Stay in loop until button is pressed
if shutterHasBeenPressed is False:
i += 1
if i == blink_speed:
overlay_2.alpha = 255
elif i == (2 * blink_speed):
overlay_2.alpha = 0
i = 0
#Restart while loop
sleep(0.1)
continue
#button has been pressed!
print("Button Pressed!")
Now, shutterHasBeenPressed has been set to False and the condition that follows is verified so that we enter the if.
the program keeps running until, unexpectedly, the button is pressed. Say, it reached <here>:
while True:
global shutterHasBeenPressed
shutterHasBeenPressed = False
#Stay in loop until button is pressed
if shutterHasBeenPressed is False:
i += 1
if i == blink_speed:
overlay_2.alpha = 255 # <here>
elif i == (2 * blink_speed):
overlay_2.alpha = 0
i = 0
#Restart while loop
sleep(0.1)
continue
#button has been pressed!
print("Button Pressed!")
At this point, shutterPressed runs, sets shutterHasBeenPressed to True. Then, back in our loop, the iteration finishes, we continue at the start of the loop and ... what's there?!
shutterHasBeenPressed = False
and the button press just went completely unnoticed!
I believe this answers your question asking what you have got wrong.
everything works except the next song doesn't play after the first is finished.
import os, random
from pygame import mixer
from pynput import keyboard
startup = 0
pause = 0
volume = 0.5
def Picker():
global startup
global volume
startup += 1
if startup > 1:
ThisSong = random.choice(os.listdir("C:\\Users\\...\\Music"))
NextSong = random.choice(os.listdir("C:\\Users\\...\\Music"))
ThisSong = NextSong
if ThisSong != NextSong:
mixer.init()
mixer.music.load("C:\\Users\\...\\Music" + ThisSong)
mixer.music.play(0)
mixer.music.set_volume(volume)
while mixer.music.get_busy():
def on_press(key):
global pause
global volume
if key == keyboard.KeyCode(char='-'):
volume -= 0.1
if volume < 0.1:
volume = 0.1
mixer.music.set_volume(volume)
if key == keyboard.KeyCode(char='='):
volume += 0.1
if volume > 1:
volume = 1
mixer.music.set_volume(volume)
if key == keyboard.KeyCode(char='['):
pause += 1
if pause == 1:
mixer.music.pause()
pause = 2
if pause == 3:
mixer.music.unpause()
pause = 0
with keyboard.Listener(on_press=on_press) as listener: listener.join()
else:
Picker()
else:
pass
Picker()
Picker()
screenshot of code
I can't get it to work, i'm very new to python so i'm probably missing something
obvious
Before starting: Thx #JGreenwell for copying the code.
Ok, so first, I’ll help you clean your code.
Things that are wrong
Having all that ThisSong and NextSong things: It won’t get saved when you restart Picker(). Either just have ThisSong, or place the ThisSong and NextSong assignment with the volume and pause variables:
.
pause = 0 # this is a problem! Next point
volume = 0.5
ThisSong = random.choice(...)
NextSong = random.choice(...)
The pause variable should be a boolean (True/False) and the pausing code should be like this:
.
pause = not pause
if pause:
# pause
else:
# unpause
Also, it would ideally be called paused
on_press and the Listener declaration should be outside the while loop, because otherwise they just keep being declared every time it loops. Then you should import time and put time.sleep(500) or something like that in the while loop, so that it doesn’t check every fraction of second.
As for the next song not playing, I don’t really know, but I’d suggest entering Picker() in the shell after the program has run (python -i script.py from CMD, IDLE leaves you in a shell by default). I would also suggest really following recommendation #3 as having them in the loop may break the loop and stop it from finishing. Most importantly, I would ask you to debug your code by adding print in every step of your code:
print(1)
if something:
print(2)
etc...
And seeing where it blocks
P.S.: The random dots are because you can’t have code in lists, so I had to exit the list.
Working solution, incase anyone else has the same problem as me in the future :)
from pygame import mixer
from pynput import keyboard
import threading
import random
import os
paused = 0
def player():
song = random.choice(os.listdir("C:\\users\\...\\desktop\\music"))
mixer.init()
mixer.music.load("C:\\users\\...\\desktop\\music\\" + song)
mixer.music.play(0)
while mixer.music.get_busy():
pass
else:
player()
def main():
t = threading.Thread(target = player, name = 'thread1', args = ())
t.start()
main()
def on_press(key):
global paused
if key == keyboard.KeyCode(char='['):
paused = not paused
if paused:
mixer.music.pause()
else:
mixer.music.unpause()
with keyboard.Listener(on_press=on_press) as listener: listener.join()
I want my program to cycle through each player, and this code does that. However, on the last player, it displays the info then instantly clears it. I want it to wait for a user to press a keydown (like space or enter) before clearing the screen. I tried implementing this with event = pygame.event.wait() but now my program just hangs when it reaches that declaration.
players = {}
for player in range(1, int(num_players)+1):
name = ask(DISPLAYSURF, "Player " + str(player) + "'s name")
player_roll = None
while player_roll is None:
for event in pygame.event.get():
if event.type == pygame.KEYDOWN:
pygame.event.clear()
while event.type != pygame.KEYDOWN:
event = pygame.event.wait()
DISPLAYSURF.fill(WHITE)
FIRST_DICE = roll_a_dice()
SECOND_DICE = roll_a_dice()
player_roll = FIRST_DICE + SECOND_DICE
players[name] = player_roll
display_dice(FIRST_DICE, SECOND_DICE)
our_roll(name)
My full code is here: https://github.com/Legitimate/Street-Dice/blob/master/main.py
Here is a video of the issue: https://youtu.be/ChxZq0bY4wk
It took a few minutes to understand what you meant, but after refactoring the list of players as the code below shows, the rest sort of rolled itself: https://github.cm/rebelclause/python_legs/blob/master/pygame/roll_the_dice.py. If it works for you, buy me a beer ;)
players = {'you': {'rolltotal': None, 'otherstuff': None }, 'me': {'rolltotal': None, 'otherstuff': None}}
def reviewvals():
print('Number of players: ', len(players)) # only counts the primary keys, the players
for player, attribdict in players.items():
for key, value in attribdict.items():
print(player, key, value)
reviewvals()
I haven't used Pygame before so I don't know if there is more efficient/ or right way of doing what you have asked for but anyway try this
Check this out
Pygame waiting the user to keypress a key
Also from docs -- this is why your program doesn't respond( which seem like it got hanged/ stuck but its not)..when it reaches event.wait()
https://www.pygame.org/docs/ref/event.html#comment_pygame_event_wait
pygame.event.wait()
wait for a single event from the queue
wait() -> EventType instance
Returns a single event from the queue. If the queue is empty this function will wait until one is created. The event is removed from the queue once it has been returned. While the program is waiting it will sleep in an idle state. This is important for programs that want to share the system with other applications.
I am currently making a game in Pygame, I have the basic game made as I followed a tutorial however know I want to improve it and make it so that after a certain amount of time (e.g. every 30 seconds or so) the game pauses and the user is asked a question and they must enter the right answer to continue playing the game. I have been looking on-line and experimenting a bit however struggling quite a lot! Here is the relevant code:
class question():
pressKeySurf, pressKeyRect = makeTextObjs('9+1.', BASICFONT, WHITE)
pressKeySurf, pressKeyRect = makeTextObjs('Press A for 10.', BASICFONT, WHITE)
pressKeySurf, pressKeyRect = makeTextObjs('Press B for 15.', BASICFONT, WHITE)
for event in pygame.event.get():
if (event.key==K_a):
showTextScreen('Correct answer') # pause until a key press
lastFallTime = time.time()
lastMoveDownTime = time.time()
lastMoveSidewaysTime = time.time()
else:
showTextScreen("Wrong")
pygame.time.set_timer(question,1000)
I have no idea if this is even going in the right direction at the moment as I can't get it to work because I think I understand the error and that I shouldn't be using a class in the timer, however not sure?
You want this to be a function, not a class. Replace class with def
The bigger problem is that your use of set_timer is incorrect. It is:
set_timer(eventid, timems)
where eventid and timems are both integers. set_timer puts an event into the event queue at the specified interval, it doesn't call any function. You have to put code in the main loop to check for that eventid and then execute the appropriate code.
Example code from this SO answer::
pygame.init()
pygame.time.set_timer(USEREVENT + 1, 100)
while True:
for event in pygame.event.get():
if event.type == USEREVENT + 1:
functionName()
if event.type == QUIT:
pygame.quite()
sys.exit()