Python GPIO raspberry pi - python

So bassicaly the user will press the picture_pin buton first, then this calls the picture_taking() function which then it should stop and wait for either (Accept_Pin or Decline_Pin) buttons to be pressed, it should not let the user to continue unless a selection is made. so when the user makes his/her selection then it go back and wait for the picture_pin button. at this stage the Accept_Pin and Decline_Pin should have no affect at all.
I have a python program that waits for a button press from the user then it runs a function to do its thing. what I would like to accomplish is, in that function I would like to also wait for another button press.
(Main.py)
----etc
## PICTURE FUNCTION ##
def picture_taking():
.....etc
returnvalue = subprocess.check_output("sudo ./" + config.layout + ".sh", shell=True)
GPIO.wait_for_edge(Accept_pin, GPIO.FALLING)
GPIO.wait_for_edge(Decline_Pin, GPIO.FALLING)
pad1alreadyPressed = False
pad4alreadyPressed = False
while True:
pad1pressed = not GPIO.input(Accept_pin)
pad4pressed = not GPIO.input(Decline_Pin)
if pad1pressed and not pad1alreadyPressed:
print "Accepted photo:" + str(returnvalue)
pad1alreadyPressed = pad1pressed
if pad4pressed and not pad4alreadyPressed:
print "Declined photo:" + str(returnvalue)
pad4alreadyPressed = pad4pressed
(This here is my Main Program)
#Main section
while True:
time.sleep(0.2)
#camera.hflip = false
camera.shutter_speed = 2000000000
camera.exposure_mode = 'off'
#camera.iso = 1000
camera.preview_fullscreen = True
camera.preview_alpha = 150
camera.start_preview()
GPIO.wait_for_edge(picture_pin, GPIO.FALLING)
picture_taking()
So in the picture_taking() function I would like to ask the user if they accept this picture or not
if they press button (GPIO 19) then they accept or (GPIO 6) as Decline
after they do there selection the program should go back and wait for the main button to select below. and these two buttons should only be selectable inside the function.
I tried this in the Picture_taking() function
when I make the selection it only accepts the "Decline_pin" button, but after I press the "Decline button" then it reads "Accept button".
The other issue is that it does not go back and wait for the Main button "picture_pin" to be pressed. it seems to be stuck here and not exiting.
I am not sure if this is something to do with Indent stuff in Python.
Thank you.

(This should be a comment, not an answer but I don't have reputation 50 yet).
Is this your actual code? I can't understand how it ever returns from the while True: clause in picture_taking(). I'd think you'd need to have something like
while (!(pad1alreadyPressed or pad4alreadyPressed)):

Related

problem rising events with keyboard clicks in PySimpleGUI

I tried to find codes online about rising events in my PySimpleGUI program by simple keyboard clicks like ENTER or Ctrl+A for instance but I couldn't just find any about it, I went to the documentation of PySimpleGUI and didn't shut my tap without learning a thing.
Here is a simple code i wrote:
import PySimpleGUI as sg
layout = [[sg.I(key='In'), sg.B('Ok')],[sg.T(enable_events=True,key='T')]]
win=sg.Window("Keyboard Events", layout)
while True:
event, value= win.read()
#close event
if event == sg.WIN_CLOSED:
break
#greeting evnt
if event in ('Ok'): #( 'OK', 'KEYBOARD ENTER EVENT'):
msg = "Hello "+value['In'] # message to show user
win['T'].update(msg) # show user message
win['In'].update("") # clear input field after submitting
win.close()
What should I say to PySimpleGUI for let it run #greeting event when I press the ENTER key? Can someone help me please? Thanks guys!
Good question! And yes, its the documentation, not you. While this may not answer your question directly, here is some useful information.
You can choose to set return_keyboard_events=True as option when creating the window (sg.Window()). This will return every key hitting an input, as well as some scrolling events, meta keys, and so on.
window.read() returns a tuple (event, values). event can be:
None (sg.WIN_CLOSED)
A string of length one with the key from an input. For example 'a'.
The key of a control. For example, 'Ok'.
A tuple with more information. For example, clicking in a table gives a tuple of (keyname, "+CLICKED+", (row, column)
A special key, such as Return:6033979789 or Meta_L:922810622.
I use this as an alternative to bind_return_key when I might have multiple text entries on the screen:
if isinstance(event, str) and event.startswith('Return'):
event = 'return ' + self.window.find_element_with_focus().key
Also, I find printing to the console is necessary to debug events:
event, values = self.window.read()
print(f" event (type:{type(ui_event)}, {ui_event}, len:({len(ui_event)})"
f" with values {ui_values}")
Option required for element
sg.Input(do_not_clear=False, key='In') clear input field after event
sg.Button('Ok', bind_return_key=True) the return key will cause this button to be pressed
import PySimpleGUI as sg
layout = [[sg.I(do_not_clear=False, key='In'), sg.B('Ok', bind_return_key=True)],[sg.T(enable_events=True,key='T')]]
win=sg.Window("Keyboard Events", layout)
while True:
event, value= win.read()
#close event
if event == sg.WIN_CLOSED:
break
#greeting evnt
if event == 'Ok':
msg = "Hello "+value['In'] # message to show user
win['T'].update(msg) # show user message
win.close()

Tkinter: GUI won't appear because of loops

My Tkinter GUI won't appear because of loops, how can i make the GUI appear without disturbing the flow of the loops? Here's the code.
for record in data:
# The rest of the code...
# Datetime and auto validation for web automation
while True:
convert_time_record = datetime.datetime.strptime(record[2], '%H:%M')
date_now = datetime.datetime.now()
time_val = record[0] == date_now.strftime('%A') and convert_time_record.strftime('%H:%M:%S') == date_now.strftime('%H:%M:%S')
if time_val and record[3] == "Yes" and record[4] == "Link":
print("time true")
chrome.open(record[5])
time.sleep(5)
os.system("taskkill /im chrome.exe /f")
break
# Check if the method was by meeting ID
elif time_val and record[3] == "Yes" and record[4] == "Meeting ID":
# Open Zoom
subprocess.call("C:\\Users\\bryan\\AppData\\Roaming\\Zoom\\bin\\Zoom.exe")
time.sleep(3)
# Locate the center of the join button then move the cursor
Click('join_button.png')
time.sleep(3)
# Write the meeting id to the text field
pyautogui.write(record[5])
# Press the enter key
pyautogui.press('enter')
time.sleep(3)
# Write the passcode to the text field
pyautogui.write(record[6])
# Press the enter key
pyautogui.press('enter')
time.sleep(8)
join_computer_audio_btn = pyautogui.locateCenterOnScreen('join_audio.png')
pyautogui.moveTo(join_computer_audio_btn)
pyautogui.click()
root.mainloop()
I've tried putting root.mainloop() inside the for-loop and while-loop but that will make the loops unable to execute the function.
You should run root.mainloop() only once.
Using loops prevents the GUI from updating, therefore consider using a different thread to run the loop and send updates to the GUI from the other thread, or use an object for maintaining the state of the loop and use a non blocking function to get the state of the object and have it update and re-set the call with the after function of tkinter.

How to click multiple times on QRadioButton but only run function once?

I have 2 radio buttons. The first one, radio1, is connected to a function func() and inside this function connects a push button, pushButton, to another function print_me().
This is the code stripped down:
radio = self.dockwidget.radioButton
radio.clicked.connect(func)
def func():
# Connect pushButton to "print_me" function
connect = self.dockwidget.pushButton
connect.clicked.connect(print_me)
def print_me():
print 'Connected'
When the user clicks radio1 and then pushButton, a message is printed. Problem is if the user clicks radio 10 times and then pushButton, the message is also printed 10 times. Or if the user clicks radio1, then radio2, and back to radio1, it will still print the message twice.
Is there a way to prevent this so that it will only print the message once when either radio button is clicked?
Have a global variable and set it to either True or False. Then add an if statement to your code (In this example the global variable name is clicked_radio_button):
radio = self.dockwidget.radioButton
radio.clicked.connect(func)
clicked_radio_button = False #Set global variable
def func():
if clicked_radio_button == False:
# Connect pushButton to "print_me" function
connect = self.dockwidget.pushButton
connect.clicked.connect(print_me)
clicked_radio_button = True #Set global variable to True
else:
pass #Do nothing if already pressed
def print_me():
print 'Connected'

How to set focus at one random window when there can show up one window from three different

I am trying to automate some application using pywinauto but there is some step that I don't know how to solve.
When I am at the main window I click "proces" buton and after this there is a possibility to open 1 window from 3 different but only 1 at a time. Please help me to solve this.
example: main window --> buton click --> 1st window (process file) or 2nd window (Your password expired, set new password) or 3rd window (this user is already logged in please kill his session and continue or break) --> process 1 of 3 windows but which will show up I don't know --> ...
You can simply check whether 1st or 2nd or 3rd window does exist:
win1st = app.Window_(title="process file")
win2nd = app.Window_(title="Your password expired, set new password")
win3rd = app.Window_(title="this user is already logged in")
if win1st.Exists(timeout=5): # in seconds
# process win1st
elif win2nd.Exists(): # default timeout is 0.5 sec
# process win2nd
elif win3rd.Exists():
# process win3rd
For existing window you may check IsVisible() or IsActive() value as well.
Methods Wait('ready') and WaitNot('visible') are useful for making sure the window is here or out. timeout can be a param if not a default one used.
More efficient way (since previously we have to wait for 5+ seconds if second or third window raised):
from pywinauto.timings import WaitUntil
WaitUntil(5, 0.1, lambda: len(app.Windows_(visible_only=True)) >= 2)
title = app.active_().WindowText()
if title == "1st case":
# process file
elif title == "2nd case":
# change a password
elif title == "3rd case":
# kill session

Kivy: How to create a 'blocking' popup/modalview?

I did find a question on this on stackoverflow, here, but I find it just doesn't answer the question, as for me, neither the Popup nor the ModalView actually 'blocks'. What I mean is, execution is moving through a function, like:
def create_file(self):
modal = ModalView(title="Just a moment", size_hint=(0.5, 0.5))
btn_ok = Button(text="Save & continue", on_press=self.save_file)
btn_no = Button(text="Discard changes", on_press=modal.dismiss)
box = BoxLayout()
box.add_widget(btn_ok)
box.add_widget(btn_no)
modal.add_widget(box)
modal.open()
print "back now!"
self.editor_main.text = ""
new = CreateView()
new.open()
And the print statement prints "back now!" and the rest of the function is immediately executed, despite the fact the ModalView just opened. I also tried this using a Popup instead of a ModalView, with the same result. I would like execution in the function to pause while I interact with the Popup/ModalView. Is there a way for this to be done built into kivy? Must I use threads? Or will I need to just find some other workaround?
You can't block like that, as that would stop the event loop and you wouldn't be able to interact with your app anymore. The easiest fix is to split this into two functions, and use on_dismiss to continue:
def create_file(self):
modal = ModalView(title="Just a moment", size_hint=(0.5, 0.5))
btn_ok = Button(text="Save & continue", on_press=self.save_file)
btn_no = Button(text="Discard changes", on_press=modal.dismiss)
box = BoxLayout()
box.add_widget(btn_ok)
box.add_widget(btn_no)
modal.add_widget(box)
modal.open()
modal.bind(on_dismiss=self._continue_create_file)
def _continue_create_file(self, *args):
print "back now!"
self.editor_main.text = ""
new = CreateView()
new.open()
It's also possible to use Twisted to make the function asynchronous, though that's a little more complicated.

Categories