tkinter key-binding won't work - python

I am trying to make a program which will react to key-presses and play certain mp3 files. Here's a piece of the code:
from pygame import mixer
from Tkinter import *
root = Tk()
def playBDT():
mixer.init()
mixer.music.load("Ba Dum Tss!.mp3")
mixer.music.play()
button2 = Button(root, command = playBDT)
button2.bind("<KeyPress-X>", playBDT)
button2.grid(row=0,column=0)
root.mainloop()
Now when i run this i get a frame with a button. When i click the button the sound plays normally. However, when i press the X key nothing happens. How can i fix it? Also if i were to play a game with this program running in the background, will the sounds play when i press the corresponding keys?

I had the same problem, but i don't know if this works for you.
button2 = Button(root, command = playBDT)
button2.focus_force()
button2.bind("<KeyPress-X>", playBDT)
button2.grid(row=0,column=0)

Related

Python Tkinter threading not working as expected on windows 10

I wrote a Tkinter program that works great except that the entire program freezes when pressing a button that calls a long running function. The user has to wait for the function to finish before doing anything else.
I found a video that showed a solution for this and it worked for the guy in the video but not for me.
The following test case shows the problem.
import tkinter as tk
from random import randint
import time
import threading
root = tk.Tk()
root.title("Test Tkinter Threading")
root.geometry("500x400")
def five_seconds():
time.sleep(5)
my_label.config(text="5 Seconds is up!")
def rando():
random_label.config(text=f'Random Number: {randint(1, 100)}')
my_label = tk.Label(root, text="Hello there!")
my_label.pack(pady=20)
# This works but hangs program while executing five_seconds()
#sleep_button = tk.Button(root, text="5 seconds", command=five_seconds)
#sleep_button.pack(pady=20)
# Supposed to let user keep chosing random numbers while five_seconds() is running.
sleep_button = tk.Button(root, text="5 seconds",
command=threading.Thread(target=five_seconds).start())
sleep_button.pack(pady=20)
random_button = tk.Button(root, text="Pick Random Number", command=rando)
random_button.pack(pady=20)
random_label = tk.Label(root, text="")
random_label.pack(pady=20)
root.mainloop()
The guy in the video was able to ckick on the sleep button and keep clicking on the random button as expected. When I run this on windows 10 I get a strange result. If I click on the random button the five_seconds() function executes (even though I never hit the sleep buttton). The random button works and does not seem to hange but the program execution is messed up.
Is there an issue with windows 10 and threading Tkinter?

Importing and using mp3s on button press

So I have coded a "copy" of the game 2048 after following a Kite youtube tutorial. I want to add a small mp3 to play anytime you click an arrow key(to move stuff around in the game) but I'm not entirely sure what i'm doing right or wrong here. How do I do this?
I've snipped the important stuff out(import music is a folder for my mp3s)
import tkinter as tk
import mp3play
import music
The two errors I'm getting are down below, the Tk in Tk() is underlined and the root in left(root...)
when i attempt to run the code like this, it highlights "import mp3play" and says there is a Syntax error. Not sure why, I have in fact installed mp3play via pip installer as well
root = Tk()
f = mp3play.load('beep.mp3'); play = lambda: f.play()
button = left(root, text = "Play", command = play)
button.pack()
root.mainloop()
in between the 2 middle sections is the def for up, down, left, and right but that would just clutter this question
Here is the stackoverflow I've referenced for it, to be honest I dont understand half of it. How can I play a sound when a tkinter button is pushed?
Take a look at this simple example using winsound which is easier to handle for small beeps.
from tkinter import *
import winsound
root = Tk()
def play():
winsound.Beep(1000, 100)
b = Button(root,text='Play',command=play)
b.pack()
root.mainloop()
winsound.Beep(1000, 100) takes two positional arguemnts, 1000 is the frequency and 100 is the duration in milliseconds.
Do let me know if any errors or doubts.
Cheers

How do I stop sounds stacking on top of each other with winsound? (Python and tkinter)

I'm trying to create a simple soundboard in python using tkinter. My aim is to just have one button, in this instance titled "bruh", where every time the button is clicked, it plays the "bruh.wav" sound.
So far it seems to work, however if I was to press the button repeatedly, the sounds would stack on top of each other as if it's a queue. How do I make it so every button press cancels any sound playing and just plays the beginning of the wav file?
I've read into the winsound module, the "PURGE" commands seems of interest but I am unsure as to how to implement it, I'm only a beginner, sorry!
from tkinter import *
root = Tk()
def leftClick(event):
import winsound
winsound.PlaySound("realbruh.wav", winsound.SND_FILENAME)
frame = Frame(root, width=600, height=600)
bruhButton = Button(root, text="bruh")
bruhButton.bind("<Button-1>", leftClick)
bruhButton.pack()
root.mainloop()
ie: If I was to spam the button, the "bruh" sound would play one after the other until it reaches the amount of times I clicked the button. How do I make it so they interrupt each other, and there is no queue thing?
If the sound is all you need and can use pygame module then try my method.
If you don't have pygame module then install it with pip install pygame. I use pygame module for all the sound effects in my tkinter projects and it works fine.
Here is how I did it:
from tkinter import *
import pygame
pygame.mixer.init() # initialise `init()` for mixer of pygame.
sound = pygame.mixer.Sound("bruh.wav") # Load the sound.
root = Tk()
def leftClick(event):
sound.stop() # Stop the ongoing sound effect.
sound.play() # Play it again from start.
frame = Frame(root, width=600, height=600)
bruhButton = Button(root, text="bruh")
bruhButton.bind("<Button-1>", leftClick)
bruhButton.pack()
root.mainloop()

Wait for button action on TkInter

Hi guys im trying to make a subprogram that waits for a button to be pressed in order to continue, in othe words: a loop that has a condidtinal, beeing the conditianal having a button pressed, and I have no idea of what can i use to do that.
Here is an easy example of what others have said, this function waits until you hit the button, when it will run the function written:
import tkinter as tk
root = tk.Tk()
root.title('waiting for button click...')
def carry_on:
# do what ever
button = tk.Button(text = 'click to continue', command = carry_on)
button.pack()
root.mainloop()
if you have a more specific question please add more information :)

how to play audio file in python?

I am just starting using python with a GUI interface. I've been experimenting with TKinter on a simple timer program. I am stuck, because I want to have a song play with the alert,but have not been able to find a solution. I am working on Linux mint. I have a message window that appears when the time is up, and i would like to start the audio along with the window, and when you exit the window, the audio stops. my code looks like this.
from Tkinter import *
import tkMessageBox
def messageWindow():
win = Toplevel()
b = Button(win, text='Times Up!',
bg="yellow", fg="green",
activebackground="purple", activeforeground="white",
command=quit)
b.pack(ipadx=root.winfo_screenwidth()/2,
ipady=root.winfo_screenheight()/2)
root.mainloop()
def alert():
#this is were i would a call the function to play mp3
messageWindow()
quit()
def start():
root.after(scale.get() * 1000, alert)
root = Tk()
minutes = Label(root, text ="Minutes: ")
minutes.grid(row=0, column=0)
scale = Scale(root, from_=1, to=60, orient=HORIZONTAL, length=450)
scale.grid(row=0, column=1)
button = Button(root,text= "Start Timing", command=start)
button.grid(row=1, column=1, pady=5, sticky=E)
root.mainloop()
pygame includes the functionality to do this. I don't know if it is the best way but it is certainly a way.
import pygame
pygame.init()
pygame.mixer.init()
sounda= pygame.mixer.Sound("desert_rustle.wav")
sounda.play()
sounda.stop()
example taken from here
Seems like you're already happy with an answer (which you accepted 3 years ago, admittedly!) but here's an alternative you could consider for future projects:
use import winsound. Pygame didn't work for me (possibly down to the fact that I'm using python 3), but more importantly, winsound probably makes audio simpler to play in the first place and it would be effective for your purposes as far as I know. You need to use a '.wav' file (as opposed to something like mp3), but it's easy to convert to that format if you look up 'online converter'.
import winsound
winsound.PlaySound('The Countdown.wav', winsound.SND_ASYNC)
Just in case you do need to stop the audio early, you can't use stop(). Instead, use
winsound.PlaySound(None, 0)
Perhaps pyglet does this anyway, but what's great about winsound.SYND_ASYNC is that it will run in conjunction with tkinter instead of halting the program/ waiting until the program finishes, to execute.

Categories