camknight15
camknight15

Reputation: 9

tkinter after function is not behaving as expected. What is the reason?

I am working on a GUI for a program that charges and discharges supercapacitors. In the CELL_DISCHARGE function, the program seems to process one iteration of countdown, but does not seem to call itself within the after function as expected. The program proceeds to the next step. This is the entire function:

def CELL_DISCHARGE():

    SCPI_instrument_frame.grid_forget()
    CELL_DISCHARGE_frame.grid()

    #cell discharge
    global Chroma_address
    global DAQ_address
    rm = pyvisa.ResourceManager()
    myChroma = rm.open_resource(Chroma_address)
    my34970A = rm.open_resource(DAQ_address)
    ttk.Label(CELL_DISCHARGE_frame, text="Cell discharge for 3 minutes").grid(row=0, column=0, pady=10)
    voltage_label = ttk.Label(CELL_DISCHARGE_frame, text="Voltage: ")
    voltage_label.grid(row=2, column=0, pady=10)
    progress = ttk.Progressbar(CELL_DISCHARGE_frame, orient="horizontal", length=180, mode="determinate")
    progress.grid(row=1, column=0, pady=10)
    progress["maximum"] = 180

    print("cell discharge for 3 minutes") #3min is for test 10 min for live
    #debug
    #time.sleep(3)
    #myChroma = rm.open_resource(Chroma_address)
    #Chroma_status = myChroma.query("*IDN?") 
    #print("Chroma Serial:" + Chroma_status)
    #print("Line - 449") 
    #time.sleep(3)
    #my34970A = rm.open_resource(DAQ_address)
    DAQ_status = my34970A.query("*IDN?")
    print("DAQ Serial:" + DAQ_status)
    myChroma.write('CHAN 1') #discharge
    myChroma.write('MODE CCL')
    myChroma.write('CURR:STAT:L1 ' + str(Discharge_curr)) #CC, static, ch 1 (discharge), 1A
    myChroma.write('LOAD ON')
    
    my34970A.write("ROUT:OPEN (@202,204,206,208,210,212,214,216,218)") #unaffected / set to discharge
    #debug*******************************************************************
    my34970A.write("ROUT:OPEN (@302,304,306,308,310,312,314,316,318)") #unaffected / set to discharge
    #debug*******************************************************************
    my34970A.write("ROUT:CLOS (@201,203,205,207,209,211,213,215,217,219)") #affected / set for in circuit
    #debug*******************************************************************
    my34970A.write("ROUT:CLOS (@301,303,305,307,309,311,313,315,317,319)") #affected / set for in circuit
    #debug*******************************************************************
    def countdown(count):
        if count > 0:
            progress["value"] = 180 - count
            CELL_DISCHARGE_frame.update_idletasks()

            print(str(count) + ": Seconds Remaining - initial discharge")
            max_range = Num_samples + 101
            for t in range(101,max_range,1):
                code = 200 + (t)
                print(code)
                #serialcomm.write(str(code).encode())
                my34970A.write('MEAS:VOLTAGE:DC? AUTO, DEF, (@' + str(t) + ')')
                voltage = float(my34970A.read())
                print("Voltage for Channel " + str(t) + " = " + str(voltage) + " VDC")
                voltage_label.config(text="Voltage: " + str(voltage))
                CELL_DISCHARGE_frame.update_idletasks()
                if msvcrt.kbhit():
                    ASCII_in = ord(msvcrt.getche())
                    if ASCII_in == 120:
                        break
            CELL_DISCHARGE_frame.after(1000, countdown, count -1)
        #time.sleep(1)
    countdown(180)

This was originally part of an issue where the GUI window was freezing because of the time.sleep function. The function has since been commented out and replaced with another function that calls itself every second instead of sleeping. I was expecting the program to count down from 180 and provide updates every second, but as mentioned before, it only processes one iteration and proceeds to the next step. I have created a separate script which runs perfectly as I expected in the main program:

import tkinter as tk
from tkinter import ttk

def test_countdown(count):
    if count > 0:
        print(f"Count: {count}")
        progress['value'] = 180 - count
        label.config(text=f"Count: {count}")
        window.after(1000, test_countdown, count - 1)
    else:
        print("Countdown complete.")

window = tk.Tk()

# GUI setup
progress = ttk.Progressbar(window, orient="horizontal", length=180, mode="determinate")
progress.grid(row=0, column=0, padx=20, pady=20)
progress["maximum"] = 180

label = ttk.Label(window, text="Starting countdown...")
label.grid(row=1, column=0, padx=20, pady=10)

# Start countdown
test_countdown(180)

window.mainloop()

I have also tried commenting out the msvcrt functions but there's no change. Why are the two programs behaving so differently?

Upvotes: 0

Views: 65

Answers (0)

Related Questions