guyd
guyd

Reputation: 733

Create a delayed process in python

Using tkinter, I wish to create a Button, when pressed it delays its switching in x seconds.

using time.sleep(x), pauses entire program, which is not my intention.

how can it be done ?

followed- class of the "button"( has a checkbutton widget, a labelwidget showing on/off label, and an entry widget to enter amount of seconds to delay )

class dev_buttons2(object):
  def __init__(self,master,buts_list):
    self.status=[]
    self.buts=[]
    self.leds=[]
    for i in range(len(buts_list)):
        var = StringVar()
        c = Checkbutton(master,text=buts_list[i], variable=var,
        indicatoron=0,command=lambda arg=[buts_list[i],var]: 
        self.cb(arg),width=10,height=2,onvalue="on",offvalue="off")
        c.grid(column=i, padx=30,pady=5,row = 1)
        var.set("off")

        var1=IntVar()
        ent=Entry(master,textvariable=var1,width=4)
        ent.grid(column=i,row=2)

        var2=StringVar()
        led=Label(master,textvariable=var2,width=4,bg="red",fg="white",
        relief="ridge")
        var2.set("off")
        led.grid(row=0,column=i)

        self.status.append([var,var2,var1])           
        self.buts.append(c)
        self.leds.append(led)

  def cb(self,but):
    indx=devices_headers.index(but[0])
    if but[1].get()=="on":
        self.status[indx][1].set(but[1].get())
        self.leds[indx].config(bg="green")
        if self.status[indx][2].get() !=0:
            print(self.status[indx][2].get() )

    if but[1].get()=="off":
        self.status[indx][1].set(but[1].get())
        self.leds[indx].config(bg="red")

a try to update cb function - gets the delay, but doen'st delay:

def cb(self,but):
    print(but[2].get())   ###(but[2] contains var1.get() -- timeout for opretion
    indx=devices_headers.index(but[0])
    device_chage_state(indx,but[1].get())
    if but[2].get() >0 :
        print ("switch off in %d seconds"%self.status[indx][2].get())
        root.after(but[2].get(),self.cb,but)

Pics of relevant part in GUI shows each button have a timeout Entry, when entered (greater than 0 ) will turn off after amount of seconds entered Manual switch pannel description

Upvotes: 0

Views: 187

Answers (1)

javidcf
javidcf

Reputation: 59701

Since you are using tkinter, the best way to do that is using the after() method. You can for example add a method like this:

def cb_delayed(self, master, but, delay_ms_var):
    master.after(delay_ms_var.get(), self.cb, but)

And then in the button creation change:

# ...
c = Checkbutton(
    master, text=buts_list[i], variable=var, indicatoron=0,
    command=lambda arg=[buts_list[i],var]: self.cb_delayed(master, arg, delay_ms_var),
    width=10, height=2, onvalue="on", offvalue="off")
# ...

Where delay_ms_var is the tkinter variable object containing the delay in milliseconds that you want to have before the change happens.

Upvotes: 2

Related Questions