0

There is an interface I developed with Tkinter. This interface has a start, a stop, and a few text frames. There are sequential test commands that run a specific procedure (function) with the start button. It prints the output of the test commands in a text frame line by line (there are also some wait/sleep states in the function).

The problem is that when the user clicks the stop button, these test steps execute all the steps without a timeout period and the output is "TEST COMPLETE". However, when the user clicks the stop button, the test step should be broken from where it was last left and the output should be "TEST INCOMPLETE - PROGRAM STOPED".

To share the code structure briefly:

def PROCEDURE_STAGE(self):
    self.must_stop = threading.Event()

    while not self.must_stop.is_set():
        self.process_text_base.insert("end", "PROGRAM STARTING..." + "\n")
        ...
        ...
        ...
        
        self.must_stop.wait(timeout=2)
        ...
        ...
        ...
        self.process_text_base.insert("end", "\n" + " TEST COMPLETE " + "\n")
        self.process_text_endline()
        self.must_stop.wait(timeout=5)
        return

    self.process_text_base.insert("end", " TEST INCOMPLETE - PROGRAM STOPED ")
    self.process_text_endline()

def START_TEST_PROCEDURE(self):
    self.t1 = threading.Thread(target=self.PROCEDURE_STAGE)
    self.t1.start()

def STOP_TEST_PROCEDURE(self):
    self.must_stop.set()

What I want to do is; the user should be able to stop this function in any situation with the "Stop" button from the outside and the loop should be broken wherever it is.

I used a flag as one of the possible solutions, but I realized that this also needs to be checked periodically in the function. It is not a method I want in terms of performance, quality, and code repetition. It is also not convenient in terms of security as it will stop after a few seconds of delay in standby/sleep states.

As a different solution, I tried creating a threading.Event() object and assigning it to the class property must_stop to terminate the loop, but I couldn't get exactly the result I wanted. It executes all the commands in the while loop one by one and then exits. Also, when using the must_stop property here, I expected it to print "TEST INCOMPLETE - PROGRAM STOPED" in the text frame, but the last command it prints is "TEST COMPLETE".

When this is done, the tkinter interface does not freeze at all. I don't want it to freeze anyway.

Codeluyor
  • 9
  • 1
  • 1
    https://stackoverflow.com/a/27051185/18505884 This answer and the rest of the post may help – mrblue6 Mar 22 '23 at 15:07
  • However, there is code that will run for about 2 minutes from the beginning to the end in my while loop, I did not write it all here. Stopping and controlling the small code block is very useful for the link you sent. Example: There is 100 lines of code in the while loop consisting of wait, sleep, for, if, elif etc. blocks and the stop command should break the while loop no matter when it comes. I hope I was able to explain... – Codeluyor Mar 22 '23 at 16:20
  • The 3rd answer (by @Khairil) on that post seems like it will help. Sorry I'm not too good with threading type stuff. EDIT: Nevermind the following, seems you tried this already and didn't work. Another thing that came to mind is, make a global var stop, and check the value of this global var after every line in your procedure. Something like ```If stop == True: break``` after every line. Then it breaks out the loop and prints("TEST INCOMPLETE..."). This is probably not very efficient though and theres surely better ways. But it should work I think – mrblue6 Mar 22 '23 at 17:02
  • What you said is an easy solution, but checking it every time causes code repetition and is very inefficient in terms of performance. Thanks anyway, this may be a way out for short codes. What I want to do should be independent of these, but I will review the link you sent again, there may be something I have overlooked. – Codeluyor Mar 23 '23 at 05:58
  • See [ask]. It's unclear and unspecific. You should post a [mre] with debugging details. And do a primary research on the thread, blocking functions. You should either implement a proper logic for doing tasks incrementally and stopping at any instance, or terminate the thread or process forcefully and ungracefully. – relent95 Mar 24 '23 at 07:54

0 Answers0