How to quit a script but not the GUI application - python

I have got a GUI aplication which includes five python scripts.
I have already found an error in the IO data, and then I'd like to include a escape condition to quit the python script and show a QT message but stay the GUI application.
one of the scripts
if len(Numero_Unidades) != 1:
quit()
else:
pass
block
but it quits python
and I want to stay in the GUI application, maintaining the main window open.
if self.ui.radioButton3.isChecked()== True:
myscript.myscript()
QtGui.QMessageBox.information(self,'message')
How can I do that?

You can start another python process to launch your script
By using os.system("script.py")

Assuming that the quit() function is the built-in quit, you can monkey-patch it and raise an error instead of quitting the whole appliaction:
import myscript
import __builtin__
def myquit():
raise RuntimeError('script quit!')
__builtin__.quit = myquit
try:
myscript.myscript()
except RuntimeError as exception:
print(exception)
else:
print('keep calm and carry on')

Related

Using Rainmeter with Python

So I have designed a layout in Rainmeter which serves as a GUI for my Voice Assistant program. Now, I want to integrate the running of Rainmeter with Python. For example, if an user already has a Rainmeter layout loaded in his/her system, then running my script will automatically override his/her layout and activate my Layout unless he/she manually changes it back to his/her own layout. This process would continue whenever my script is run. It basically goes like this: The user runs the script, it checks whether any other skin is loaded or not (Assuming that Rainmeter is installed on the system). If any other skin is loaded, it overrides the skin with my one else it bypasses the override function and directly loads my skin.
I have no idea on how to achieve this thing. I have successfully written the lines to start and exit rainmeter with python but I don't know anything about how to load the layouts! Please help!
Here is the script I have written to start and exit Rainmeter:
import os
trigger = input()
if trigger == "y":
try:
os.startfile("C:\Program Files\Rainmeter\Rainmeter.exe")
print("Rainmeter started successfully")
except:
print("There was an error")
trigger = input()
if trigger == "exit":
try:
os.system("taskkill /f /im Rainmeter.exe")
print("Rainmeter closed successfully")
except:
print("There was an error")
You can use the following code to load a Rainmeter Layout:
import subprocess
subprocess.call(["C:\Program Files\Rainmeter\Rainmeter.exe", "!LoadLayout", "abcd"])
Here we are using rainmeter bangs to load the layout. Change abcd with name of your layout.

Is there a way to implement a program termination protocol?

In my case, I am handling databases throughout the entire runtime of my program, and so I need to keep my 'cursor' open for the entire program. Is there anyway I can implement a termination protocol, so that when I terminate its execution or an error arises, I am able to run this quick piece of code that simply closes the cursor (I am using python sockets btw).
I would suspect I could do something like this:
if __name__ == "__main__":
Menu()
cursor.close()
However, the only reason that this doesn't work in my case is that Menu is simply starting up threads, and so its execution continues on, returning me back to cursor.close() whilst my program continues to run.
I'm not sure if there is a way to get around this problem.
Yes, you could use the signal library in python to achieve some of this functionality, in particular, capturing program termination as well interrupts to the program like ctrl + c. Example:
# a function to register the signal handlers
# once the program terminates or is halted by an interrupt like ctrl + c it executes the quit_gracefully function
def register_signal_handler():
signal.signal(signal.SIGINT, quit_gracefully)
signal.signal(signal.SIGTERM, quit_gracefully)
return
def quit_gracefully():
# close connections etc.
in case of a different error you could use a try-except block which handles the error and runs the quit_gracefully function in the except.
try:
# some code
except:
quit_gracefully()
EDIT:
this is a good post on signal. How do I capture SIGINT in Python?
You can also use the atexit module: https://docs.python.org/3/library/atexit.html.
Something like this:
import atexit
#atexit.register
def close_cursor():
print("Closing cursor before exiting.")
cursor.close()

Exiting out of a program through a menu option

I need to say first and foremost, I am just learning Python.
I am making a simple python program that has a menu option for exiting the program by using a function I called exit. I have tried making the exit function just call break, but I am getting an error when the exit function is called.
Any help would be greatly appreciated.
Sorry for not posting code earlier....
def exit():
break
evade = evade_fw()
# Main program running dialogue
def main(): # menu goes here
opt_list = [xsl_file,
basic_loud_scan,
fw_main,
exit
]
Just forget about your own exit() function. You can simply do:
from sys import exit
And the exit() function from sys module will do the job.
It's also worth to know what happens under the hood. Function sys.exit() actually throws a special exception. You can do it as well explicitly and without importing anything:
raise SystemExit()
break is for breaking out of for or while loops, but it must be called from within the loop. I'm guessing that you expect the break to break out of your program's main event loop from an event handler, and that is not going to work because, as aforementioned, the break must be within the loop itself.
Instead your exit function can clean up any resources, e.g. open files, database connections, etc. then call [sys.exit()][1] which will cause the Python interpreter to terminate. You can optionally pass a status code to sys.exit() which will be the system exit status available to shell scripts and batch files.
import sys
def exit():
# clean up resources
sys.exit() # defaults to status 0 == success

Python/Calling python scripts within bash terminal: What exactly happens when user presses Ctrl-C?

I need help with controlling a python script. I want to run a script that controls two robots. A routine consists of a series of motions which either move the arm or move the gripper. The form of the code is as follows:
def robot_exec():
# List of robot arm poses:
*many_many_lines_of_position_vectors*
# List of robot gripper poses:
*open position*
*close position*
while 1:
*Call a function that moves the robot arm(s) to a position on the list*
*Call a function that moves the robot gripper(s) to a position on the list*
*continue calling functions many times until the desired routine is complete*
n = raw_input("Restart the routine? (Y/N)")
if n.strip() == 'n' or 'N':
break
elif n.strip() == 'y' or 'Y':
continue
else:
print "Invalid input. Exiting..."
break
If the routine is complete (i.e. every function was called), it asks if I want to restart, and if I choose yes, behaves as normal, which is good.
But, if I press ctrl-C in the middle of the routine, the message "Restart the routine?" still pops up and asks for input, and I don't want that. What I want is either one of the following:
if and only if the user presses ctrl-C, completely exit everything, no questions asked.
if and only if the user presses ctrl-C, return the robots to home position (defined in that list of arm poses) and then completely exit everything.
My main question is, how does ctrl-C actually work? I thought it would just exit the script but in actuality it still prints stuff and asks for input. A subset of that broad question is, how can I just get the desired behavior (completely exit everything when pressing ctrl-C)?
I realize this is a clunky way of doing what I need the robots to do, but it is the best way I can think of with my limited knowledge of python.
Thank you,
-Adrian
The comments/answers about signals are technically correct (on UNIX), but in Python the CTRL+C handling is neatly wrapped away from you. What happens in a Python program is that at the point where you press CTRL+C, a KeyboardInterrupt exception is raised.
Now, your problem seems to be in the code that you have removed from the listing, i.e., in the "calling robot routines" part. That code catches the KeyboardInterrupt.
I guess either your code or library code that you call does something like:
try:
# some long running code
# ...
except:
# something, or just pass
Note the naked except:. Naked excepts are almost always a bad thing. Instead you or the library should do:
try:
# some long running code
# ...
except Exception:
# something to fix the situation
Using except Exception: does not catch the KeyboardInterrupt exception, which will let you handle it appropriately, or just let the program exit. Have a look at the Exception class hierarchy.
What exactly happens when user presses Ctrl-C?
A signal is raised.
how can I just get the desired behavior
>>> import signal
>>> def handler(sig, stack_frame):
... print "Handled"
...
>>> signal.signal(signal.SIGINT, handler)
<built-in function default_int_handler>
^C # <--- typed ctrl-c here
>>> Handled
See the doc of signal for details.
Please note: on Linux I use signal.SIGINT. On Windows, maybe it is signal.CTRL_C_EVENT instead.
you can handle Ctrl_C with this code :
#!/usr/bin/env python
import signal
import sys
def signal_handler(signal, frame):
#write your command here for example i write print below :
print('You pressed Ctrl+C!')
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
print('Press Ctrl+C')
signal.pause()

Ending an infinite while loop

I currently have code that basically runs an infinite while loop to collect data from users. Constantly updating dictionaries/lists based on the contents of a text file. For reference:
while (True):
IDs2=UpdatePoints(value,IDs2)
time.sleep(10)
Basically, my problem is that I do not know when I want this to end, but after this while loop runs I want to use the information collected, not lose it by crashing my program. Is there a simple, elegant way to simply exit out of the while loop whenever I want? Something like pressing a certain key on my keyboard would be awesome.
You can try wrapping that code in a try/except block, because keyboard interrupts are just exceptions:
try:
while True:
IDs2=UpdatePoints(value,IDs2)
time.sleep(10)
except KeyboardInterrupt:
print('interrupted!')
Then you can exit the loop with CTRL-C.
You could use exceptions. But you only should use exceptions for stuff that isn't supposed to happen. So not for this.
That is why I recommand signals:
import sys, signal
def signal_handler(signal, frame):
print("\nprogram exiting gracefully")
sys.exit(0)
signal.signal(signal.SIGINT, signal_handler)
you should put this on the beginning of your program and when you press ctrl+c wherever in your program it will shut down gracefully
Code explanation:
You import sys and signals.
Then you make a function that executes on exit. sys.exit(0) stops the programming with exit code 0 (the code that says, everything went good).
When the program get the SIGINT either by ctrl-c or by a kill command in the terminal you program will shutdown gracefully.
I think the easiest solution would be to catch the KeyboardInterrupt when the interrupt key is pressed, and use that to determine when to stop the loop.
except KeyboardInterrupt:
break
The disadvantage of looking for this exception is that it may prevent the user from terminating the program while the loop is still running.
I use python to track stock prices and submit automated buy/sell commands on my portfolio. Long story short, I wanted my tracking program to ping the data server for info, and place trades off of the information gathered, but I also wanted to save the stock data for future reference, on top of being able to start/stop the program whenever I wanted.
What ended up working for me was the following:
trigger = True
while trigger == True:
try:
(tracking program and purchasing program conditions here)
except:
trigger = False
print('shutdown initialized')
df = pd.DataFrame...
save all the datas
print('shutdown complete')
etc.
From here, while the program is in the forever loop spamming away requests for data from my broker's API, using the CTRL-C keyboard interrupt function toggles the exception to the try loop, which nullifies the while loop, allowing the script to finalize the data saving protocol without bringing the entire script to an abrupt halt.
Hope this helps!
Resultant
I would suggest using the try, except syntax within a loop if you are running on an IPYNB file in Google Colab or Jupyter, like:
while True:
try:
IDs2=UpdatePoints(value,IDs2)
time.sleep(10)
except KeyboardInterrupt:
break
except:
continue
the last except is for any other error if occurs the loop will resume
You can catch the KeyboardInterrupt error in Python:
try:
while 1>0:
IDs2=UpdatePoints(value,IDs2)
time.sleep(10)
except KeyboardInterrupt:
print('While loop ended!')
Also, instead of saying:
while True:
It looks more professional to use:
while 1>0:
To read more about Python Error handling (try, except, etc.):
https://www.w3schools.com/python/python_try_except.asp
or:
https://www.w3schools.com/python/gloss_python_try_finally.asp

Categories

Resources