0

I have an initial value CamTimeObsVar = 50 and I want make it reducing as long as button btnCamTimeL is being pressed. When I release the button to stop reducing. I tried the following code but the variable reduced only once. Is it possible to control the changing speed? I tried sleep(0.1) but it does not work.

Thanks in advance.

My code is:

from tkinter import *
from time import sleep

root = Tk()
root.geometry('800x480')
Pressed = False

def CamTimeObsVarL(event):
    global CamTimeObsVar
    
    print("Button is pressed")
    CamTimeObsVar = CamTimeObsVar - 1
    lblCamTime['text'] = str(CamTimeObsVar) + ' sec'
    sleep(0.1)
    

def Stop(event):
    global Pressed
    print("Stopping")
    Pressed = False

myFrame = Frame(root, width = 800, height=480)
CamTimeObsVar = 100
lblCamTime = Label(root)
lblCamTime.place(x=650, y=50)
lblCamTime['text'] = str(CamTimeObsVar) + ' sec'
btnCamTimeL = Button(root, text ='L', width=1, height=1, bg='red')
btnCamTimeL.place(x=620, y=50)

btnCamTimeL.bind('<ButtonPress-1>',CamTimeObsVarL)
btnCamTimeL.bind('<ButtonRelease-1>',Stop)

root.mainloop()
acw1668
  • 40,144
  • 5
  • 22
  • 34
Psiloritis
  • 17
  • 5

2 Answers2

1

You can start a periodically update using after() when the button is pressed, then cancel the after() task when the button is released:

def CamTimeObsVarL(event=None):
    global after_id, CamTimeObsVar
    print("Button is pressed")
    if CamTimeObsVar > 0:
        CamTimeObsVar -= 1
        lblCamTime['text'] = str(CamTimeObsVar) + ' sec'
        after_id = lblCamTime.after(100, CamTimeObsVarL) # update again 0.1 second later

def Stop(event):
    global after_id
    print("Stopping")
    if after_id:
        lblCamTime.after_cancel(after_id)
        after_id = None
acw1668
  • 40,144
  • 5
  • 22
  • 34
  • @Psiloritis If it solves your question, you are appreciated to accept it as an answer by clicking the `tick` beside the answer. – acw1668 Jan 13 '21 at 10:35
1

Another way of doing it is to bind both ButtonPress event and ButtonRelease events to the same event handler and use a check like stop. This stop would be False initially and will become True only if the event.type==5, that is mouse release event.

from tkinter import *
from time import sleep

root = Tk()
root.geometry('800x480')
stop = False

def CamTimeObsVarL(event=None):
    global CamTimeObsVar, stop

    if event and int(event.type) == 4:
        stop = False

    if event and int(event.type) == 5:
        print('stopping')
        stop = True
    
    if stop==False:
        CamTimeObsVar = CamTimeObsVar - 1
        lblCamTime['text'] = str(CamTimeObsVar) + ' sec'
        print("Button is pressed")
        a = root.after(100, CamTimeObsVarL)

myFrame = Frame(root, width = 800, height=480)
CamTimeObsVar = 100
lblCamTime = Label(root)
lblCamTime.place(x=650, y=50)
lblCamTime['text'] = str(CamTimeObsVar) + ' sec'
btnCamTimeL = Button(root, text ='L', width=1, height=1, bg='red')
btnCamTimeL.place(x=620, y=50)

btnCamTimeL.bind('<ButtonPress-1>',CamTimeObsVarL)
btnCamTimeL.bind('<ButtonRelease-1>',CamTimeObsVarL, '+')

root.mainloop()

Or you could also bind Release event and press event to different handlers as shown below.


def CamTimeObsVarL(event=None):
    global CamTimeObsVar, stop

    if event and int(event.type) == 4:
        stop = False
    
    if stop==False:
        CamTimeObsVar = CamTimeObsVar - 1
        lblCamTime['text'] = str(CamTimeObsVar) + ' sec'
        print("Button is pressed")
        a = root.after(100, CamTimeObsVarL)

def end(event):
    global stop
    stop = True


btnCamTimeL.bind('<ButtonPress-1>',CamTimeObsVarL)
btnCamTimeL.bind('<ButtonRelease-1>',end)

JacksonPro
  • 3,135
  • 2
  • 6
  • 29