Currently I am making a very simple interface which asks user to input parameters for a test and then run the test. The test is running brushless dc motor for several minutes. So when the run button is pressed the button is engaged for the time period till the function is finished executing. I have another stop button which should kill the test but currently cant use it since the run button is kept pressed till the function is finished executing and stop button cant be used during the test. I want to stop the test with pressing the stop button even if the run button function is currently being executed. The run button should release and the function should continuously check the stop function for stopping the test. Let me know how this can be executed.
Your problem is that all your code it taking place sequentially in a single thread. Once your first button is pressed, all of the results of that pressing are followed through before anything else can happen.
You can avoid this by running the motor stuff in a separate thread. Your stop button will then need to interrupt that thread.
Related
i made a little GUI to take input from the user one of the main process is withing a thread and since that command starts there's an event that triggers an endless progress bar to simulate waitting time.
But i want to make it really usefull, but i can't find a way stop the progressbar when the process is done.
so any help on that, would be great.
You can place a return statement in the code that will be hit when the thread is done
I have a thread that is running and a 'stop thread' button which when clicked calls a method that calls the terminate() of the thread. I have a QMessage Box that confirms the stop button before it terminates. The functionality is as expected but if I then start the thread again and click the close button then I get the confirmation MessageBox, I then select confirm and the thread stops but another confirmation box appears. It continues in this manner - if I run it 3 times I have to confirm three boxes, 4 I get 4 etc. The first box will terminate the thread in all cases. It seems like the MessageBox is not being destroyed properly each time it appears so they just build up? Not sure what's going on.
See below code. I have a thread 'my_thread' and a button connected to the function 'stop_thread' outlined below.
def stop_thread(self):
prompt=QWidgets.QMessageBox.question(self, 'Stop!', 'Are you sure you want to stop thread?', QtWidgets.QMessageBox.Yes, QtWidgets.QMessageBox.No)
if prompt == QtWidgets.QMessageBox.Yes:
self.my_thread.terminate()
else:
pass
I would expect each time I start and then stop the thread using the button I get one confirmation box appearing and upon selecting 'Yes' the thread will terminate. In reality the thread terminates but I get multiple MessageBoxes appearing one after the other - the number of them corresponds to how many times I have started the thread.
Solved it - It was because I was connecting the stop_button to the function outlined above in the function that I used to start the thread. So every time I started a thread I connected it again and called the function an extra time. What I didn't know was you could connect buttons to a function more than once (or multiple functions) but you learn something new everyday.
To fix I moved the connection of the stop button to the stop_thread function to the main class and now works great.
I have a sensor() method, and I use root.after(200, sensor) to run it all the time. I also have a function set_speed() in it which can set the speed of motor. When the sensor detects something, it will run
set_speed(100)
sleep(3)
set_speed(0)
Now I need to add another button, when the sensor detects something, we can press the button the break the sleep (bu the sensor is still running).
It seems that I need to add another root.after to create another thread or something, I have tried for a while but was not able to complete it.
Problem solved. We can simply use another after to build another thread which will be run 3 seconds later and set the speed as 0.
set_speed(100)
root.after(3000, stop)
.....
def stop():
set_speed(0)
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.
I'm working on a GUI program in which I already bind a start button with one event, and when I click the start button, the event runs as I like. My question is, if I want my program to start the event immediately after the GUI program starts, which means the start button is immediately being "clicked" once the program starts, how do I do it?
In the main frame constructor set a one-shot timer with interval 0 that fires the event.
In the __init__( ) for your main frame put this:
wx.CallAfter( func_name )