Skip to content Skip to sidebar Skip to footer

Why Isn't Python Waiting For My Function To Finish?

So I'm using tkinter and Python to write an app to control some devices over serial. In this case I am controlling a temperature bath and I have a simple function that waits until

Solution 1:

It does wait for wait_for_temp to complete. wait_for_temp will return almost immediately, however. Calling after doesn't prevent it from returning. Quite the contrary, calling after allows it to return without waiting.

Writing a GUI is different from writing non-GUI programs. A GUI is already in a perpetual state of waiting. Instead of writing a function that itself waits, you need to write code that can respond to events.

For example, you can create a <<TemperatureReached>> event that can be triggered when the temperature hits a given value. You can then bind a function to be called when that event triggers.

It would look something like this:

defcontrol_fcn()
    bc = Bath_Controller()

    # set the temperature I want
    set_temp = 16.0
    bc.write_temp(set_temp)

    # arrange for notifyUser to be called when the target# temperature has been reached
    app.bind("<<TemperatureReached>>", self.notifyUser)

    # periodically check the temp
    self.check_temp(set_temp)

defnotifyUser(event):
    print("Temperature reached")

defcheck_temp(self, set_temp):
    current_temp = self.read_temp()
    if (current_temp < set_temp + .05) and (current_temp > set_temp - .05):
        # temperature reached; send an event
        app.event_generate("<<TemperatureReached>>")
    else:
        # temperature not reached. Check again in 10 seconds
        app.after(10000, self.check_temp, set_temp)

Solution 2:

The after method is designed to return immediately. The point of useing after rather than a while True: loop is that it returns immediately and does not lockup the GUI. To get what you want you will have to split it up:

defcontrol_fcn()
  bc = Bath_Controller()

  # set the temperature I want
  set_temp = 16.0
  bc.write_temp(set_temp)

  print("Commanding temp to " + str(set_temp))

  bc.turn_on()

  # wait for bath temp to be within .1 of the commanded temp# this function prints out a "Temperature reached. Carry on." statement when done
  bc.wait_for_temp(set_temp)

defdone():
  print("I didn't wait for you friend.")

# in my Bath_Controller() class I have the following functiondefwait_for_temp(self, set_temp):
  current_temp = self.read_temp()
  if (current_temp < set_temp + .05) and (current_temp > set_temp - .05):
    print("Temperature reached. Carry on.")
    done()
  else:
    print("Waiting for temperature equilibration.\n Current temp is:")
    # app here is my root window in tkinter
    app.after(10000, lambda: self.wait_for_temp(set_temp))

Solution 3:

In app.after() you are basically saying run this piece of code after 10 seconds, however you're not instructing the processor to wait 10 seconds in conjunction.

The simple solution is to wrap your function wait_for_temp() in a proper while loop and wait until you have the desired output, i.e.:

# in my Bath_Controller() class I have the following functiondefwait_for_temp(self, set_temp):
    while1:
        current_temp = self.read_temp()
        if (current_temp < set_temp + .05) and (current_temp > set_temp - .05):
            print("Temperature reached. Carry on.")
            return
        time.sleep(1)

Post a Comment for "Why Isn't Python Waiting For My Function To Finish?"