I created a GUI with PyQt which implements the buttons "Start" and "Stop".
When I click on "Start" a huge python Script is started. The function of "Stop" has to end this python script, but when I start the script it runs and I can't stop it. I even can't activate anything else on the GUI and I get no reaction from it. So i have to wait the long time until the python script ends.
How can I implement the methods so that I can interrupt the script with the "Stop" button even when I want?
Since you do everything in the QButton.clicked signal, your GUI locks up until you exit that function.
My solution i used in a small project was to seperate it into a GUI and worker process.
Use multiprocessing.Process to do your processing and have it send the results over a multiprocessing.Pipe.
The worker also has a second Pipe to recieve commands (my project just uses one command - exit)
In the GUI, you create 2 Pipes: one for results, one for commands.
Initialize the worker with both pipes and start the process.
The next step would be to have a QTimer poll the pipe for results and display them.
By doing so, your UI stays responsive while the calculations happen in the background.
Related
I'm doing a small project related to data engineering. I have 2 processes. First is responsible for sorting, analysing and making graphs. The second is only the loading bar, simple gui which is shown to user why data operators are done. The loading bar stops when the information from multiprocessing Event is send. But I want to stop whole function from second process when user close the window. Basically I want to stop python script when the window is closed. I tried with options:
sys.exit(0), exit(0), quit() and os._exit(0) but every option kills only the process instead of running whole script. I want to do similar option to ctrl+c in vsc terminal. Did I missed sth or it doesn't work in general?
I know that I can run a background process in python using subprocess. But the problem is that when I make a gui and then use subprocess with close_fds=True parameter, the window changes to not responding.
So, what I want is that I need to create a background process but it should run separately along with the main process and when that process is done, it should again combine with the main process.
BTW, I am using PySide2 as the gui framework
Any help would be appreciated
I think what would be more beneficial to you would be threading, you are able to start a process in another thread without blocking the main thread which runs your gui. Once the other thread has completed its task it will join the main thread
I am a bit confused with multiprocessing. I have a video processing script which can be run from the command line or launched from a PySide application using a subprocess call. The script seems to run fine from the command line and basically initializes a pool of workers which each process a separate video file.
When I run the program however the OS tells me my program is not responding. I would like to make use of all the cores on my system for multiprocessing but I would also like to prevent this annoyance. What should I do I get around this? Do I start the initial script in a thread or something?
As you are speaking of PySide, I assume you program is a GUI one. In a GUI program all processing must occurs in a worker thread if you want to keep the UI responsive. So yes, the initial script must be start in a thread distinct from main thread (main one is reserved for UI)
I have a script which runs 2 threads infinitely. (Each thread is an infinite while loop) Whenever I run it normally, I use ctrl + Z or ctrl + C to stop its execution (depending on the OS). But ever since I added it to the /etc/rc.local file in Linux, for automatic startup upon boot, I am unable to use these commands to forcefully exit.
This has forced me to include something in the python script itself to cleanly exit when I type a certain key. How do I do so?
The problem is that I'm running a multithreaded application, which runs continuously and does not wait for any user inputs.
I added this to the start of a loop in my thread-
ip = raw_input()
if ip == 'quit':
quit()
But this will NOT work since it blocks for a user input, and stops the script. I don't want the script to be affected at all by this. I just want it to respond when I want to stop it. My question is not what command to use (which is explained here- Python exit commands - why so many and when should each be used?), but how I should use it without affecting the flow of my program.
Keep the code that handles the KeyboardInterrupt and send it an INT signal to stop the program: kill -INT $pid from the shell, where $pid is the process ID (PID) of the program. That's essentially the same as pressing CTRL+C in a shell where the program runs in the foreground.
Writing the program's PID into a file right after it started, either from within the program itself or from the code which started it asynchronously, makes it easier to send a signal later, without the need to search for the process in the process list.
One way is to have the threads examine a global variable as a part of their loop, and terminate (break out of the loop and terminate, that is) when the variable is set.
The main thread can then simply set the variable and join() all existing threads before terminating. You should be aware that if the individual threads are blocked waiting for some event to occur before they next check whether the global variable has been set, then they will hang anyway until that event occurs.
Python have been really bumpy for me, because the last time I created a GUI client, the client seems to hang when spawning a process, calling a shell script, and calling outside application.
This have been my major problem with Python since then, and now I'm in a new project, can someone give me pointers, and a word of advice in order for my GUI python application to still be interactive when spawning another process?
Simplest (not necessarily "best" in an abstract sense): spawn the subprocess in a separate thread, communicating results back to the main thread via a Queue.Queue instance -- the main thread must periodically check that queue to see if the results have arrived yet, but periodic polling isn't hard to arrange in any event loop.
Your main GUI thread will freeze if you spawn off a process and wait for it to completely. Often, you can simply use subprocess and poll it now and then for completion rather than waiting for it to finish. This will keep your GUI from freezing.