I want to make 2 buttons (+ and -) that can change the volume. But if I want to increase the volume more, I'd like to can keep the button pressed. Any ideas how to check if a button remains pressed by the user?
def volumeUp():
currentVolume = m.getvolume()[0]
volumeSlider.set(currentVolume + 5)
def volumeDown():
currentVolume = m.getvolume()[0]
volumeSlider.set(currentVolume - 5)
volumeDownButton = Button(win, text = "-", font = myFont, command = volumeDown, height = 1, width = 1)
volumeDownButton.pack(side = BOTTOM)
volumeUpButton = Button(win, text = "+", font = myFont, command = volumeUp, height = 1, width = 1)
volumeUpButton.pack(side = BOTTOM)
What you can do is make the Button press fire a function that alters the volume and then schedules itself to be run again after a certain amount of time (eg 100 ms). Then when the Button is released, you can cancel the scheduled repeat of the function that alters the volume to break the loop.
I've altered your code a bit to make an example:
from tkinter import *
win = Tk()
def volumeUpPress(e=None):
global up_after
currentVolume = volumeSlider.get()
volumeSlider.set(currentVolume + 2)
up_after = win.after(100, volumeUpPress)
def volumeUpRelease(e=None):
global up_after
win.after_cancel(up_after)
def volumeDownPress(e=None):
global down_after
currentVolume = volumeSlider.get()
volumeSlider.set(currentVolume - 2)
down_after = win.after(100, volumeDownPress)
def volumeDownRelease(e=None):
global down_after
win.after_cancel(down_after)
volumeSlider = Scale(win, from_=0, to=100, orient=HORIZONTAL)
volumeSlider.pack()
volumeDownButton = Button(win, text = "-", height = 1, width = 1)
volumeDownButton.pack(side = BOTTOM)
volumeDownButton.bind("<Button-1>", volumeDownPress)
volumeDownButton.bind("<ButtonRelease-1>", volumeDownRelease)
volumeUpButton = Button(win, text = "+", height = 1, width = 1)
volumeUpButton.pack(side = BOTTOM)
volumeUpButton.bind("<Button-1>", volumeUpPress)
volumeUpButton.bind("<ButtonRelease-1>", volumeUpRelease)
win.mainloop()
Things to note:
command
since that doesn't give you the flexibility of knowing when the Button is released. Instead I made two binds, one for when the Button is pressed, one for when it is released. after
method to schedule a new call to the same function after a set number of milliseconds, I save a reference to this scheduled function in a global variabel, to be able to use it again in the release function to cancel it with after_cancel
.bind
calls functions with an event object, while after
calls a function without arguments, because both call the same function, I made it so that the function can be called both with and without argument ( e=None
) An alternative to fhdrsdg's answer that also uses after
would be to measure the state
value of the Button
and detect whether it is currently active
, to do this we bind a function to the Button
which checks the state
and then increments a value if the state
is active
before using after
to call the function again after a short delay:
from tkinter import *
class App():
def __init__(self, root):
self.root = root
self.button = Button(self.root, text="Increment")
self.value = 0
self.button.pack()
self.button.bind("<Button-1>", lambda x: self.root.after(10, self.increment))
def increment(self, *args):
if self.button["state"] == "active":
self.value += 1
print(self.value)
self.root.after(10, self.increment)
root = Tk()
App(root)
root.mainloop()
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.