Importing and using mp3s on button press - python

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

Related

Move tkinter button randomly on mouse hover

I'm trying to make a button move randomly to coordinates in lists.
It moves the first time I hover on it each time I run the programme and never after and I can't figure it out, I'm a total noob, though and frankly I'm amazed it works at all.
I hate asking questions but I've been trying to solve this for weeks so I appreciate anyone's help..
import tkinter as tk
from tkinter import *
import random
root = tk.Tk()
root.title('Press me')
root.geometry('1280x800')
img=PhotoImage(file='red_button_crop.png')
my_label=Label(root, text="",font='helvetica,12')
my_label.pack(pady=50)
but_loc_x=[200,600,1000]
but_loc_y=[200,350,600]
but_pos_x=random.choice(but_loc_x)
but_pos_y=random.choice(but_loc_y)
def press():
my_label.config(text="You pressed me.\n Well done\nYou are as clever as a monkey.\n Not one of the good ones tho")
root.after(1500,root.destroy)
def button_hover(e):
root.after(250)
button.place_configure(x=but_pos_x,y=but_pos_y)
#def unhover(e):
# root.after(500)
#button.place_configure(x=600,y=350)
button =tk.Button(root,image=img,borderwidth=0,command=press)
button.place(x=600,y=350,anchor=CENTER)
button.bind("<Enter>",button_hover)
#button.bind("<Leave>",unhover)
root.mainloop()
I've tried implementing various bit of code I searched up on the net but I don't know enough to work it out
Importantly, as one of the comments suggests, the button is moving every time you hover over it, so your code was in fact correct.
However, because the coordinates are set outside of the function it always hovers to the same place (so it appears like it was not moving).
The changes that correct to code to the desired output are below.
removed from tkinter import * and used the tk alias as it should be.
moved the random button positions into the function (see comment with arrow).
This is the corrected version of the code:
import tkinter as tk
# from tkinter import *
import random
root = tk.Tk()
root.title('Press me')
root.geometry('1280x800')
img=tk.PhotoImage(file='red_button_crop.png')
my_label=tk.Label(root, text="",font='helvetica,12')
my_label.pack(pady=50)
but_loc_x=[200,600,1000]
but_loc_y=[200,350,600]
def press():
my_label.config(text="You pressed me.\n Well done\nYou are as clever as a monkey.\n Not one of the good ones tho")
root.after(1500,root.destroy)
def button_hover(e):
root.after(250)
but_pos_x=random.choice(but_loc_x) # <----- moved into the function
but_pos_y=random.choice(but_loc_y) # <----- moved into the function
button.place_configure(x=but_pos_x,y=but_pos_y)
#def unhover(e):
# root.after(500)
#button.place_configure(x=600,y=350)
button =tk.Button(root,image=img,borderwidth=0,command=press)
button.place(x=600,y=350,anchor=tk.CENTER)
button.bind("<Enter>",button_hover)
#button.bind("<Leave>",unhover)
root.mainloop()
Result:
the image red_button_crop.png now moves randomly when hovered over.

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()

Tkinter tkMessageBox disables Tkinter key bindings

Here's a very simple example:
from Tkinter import *
import tkMessageBox
def quit(event):
exit()
root = Tk()
root.bind("<Escape>", quit)
#tkMessageBox.showinfo("title", "message")
root.mainloop()
If I run the code exactly as it is, the program will terminate when Esc is hit. Now, if I un-comment the tkMessageBox line, the binding is "lost" after closing the message box, i.e. pressing Esc won't do anything anymore. This is happening in Python 2.7. Can you please verify if this is happening also to you? And let me know about your Python version.
Here is a way to "by-pass" the problem. It's a different approach, but it might help:
from Tkinter import *
import tkMessageBox
def msg_test():
tkMessageBox.showinfo("title", "message")
def quit(event):
exit()
root = Tk()
root.bind("<Escape>", quit)
btn = Button(root, text="Check", command=msg_test); btn.pack()
root.mainloop()
Using tkMessageBox via a button click, doesn't affect key binding, i.e. pressing Esc continues to work.
If I understand the problem, you get the bad behavior if you call tkMessageBox.showInfo() before calling mainloop. If that is so, I think this is a known bug in tkinter on windows.
The solution is simple: don't do that. If you need a dialog to show at the very start of your program, use after to schedule it to appear after mainloop has started, or call update before displaying the dialog.
For example:
root = Tk()
root.after_idle(msg_test)
root.mainloop()
The original bug was reported quite some time ago, and the tk bug database has moved once or twice so I'm having a hard time finding a link to the original issue. Here's one issue from 2000/2001 that mentions it: https://core.tcl.tk/tk/tktview?name=220431ffff (see the comments at the very bottom of the bug report).
The report claims it was fixed, but maybe it has shown up again, or maybe your version of tkinter is old enough to still have the bug.

Python Tk() Button command not completely working

I'm quite new to python programming and have quite a basic question which I can't seem to resolve myself - I hope someone might be able to shed some light on this!
I created a .py file which runs a basic Rock, Paper, Scissors game between a user and the (random) computer. This uses a GUI via a tk() and works absolutely fine.
Then, I created another .py file, this time to create an overall menu GUI, from which I could choose to run my Rock, Paper, Scissors game. I can create this tk() fine, the button to select the RPS game, the game loads up, but this time it doesn't work at all! I can press the buttons, but they don't progress the game.
Here's my code for the game.py:
from tkinter import *
from tkinter.ttk import *
import random
def gui():
<game code goes in here, including other functions>
root=Tk()
root.title("Rock, Paper, Scissors")
# more code to define what this looks like
# including a Frame, buttons, labels, etc>
if __name__=='__main__':
gui()
And then I created the overall game menu, menu.py:
from tkinter import *
from tkinter.ttk import *
import random
import game
main=Tk()
main.title("J's games")
mainframe=Frame(main,height=200,width=500)
mainframe.pack_propagate(0)
mainframe.pack(padx=5,pady=5)
intro=Label(mainframe,
text="""Welcome to J's Games. Please make your (RPS) choice.""")
intro.pack(side=TOP)
rps_button=Button(mainframe, text="Rock,Paper,Scissors", command=game.gui)
rps_button.pack()
test_button=Button(mainframe,text="Test Button")
test_button.pack()
exit_button=Button(mainframe,text="Quit", command=main.destroy)
exit_button.pack(side=BOTTOM)
main.mainloop()
If anyone can see something obvious, please let me know. I'm confused as to why it works on its own, but not when I incorporate it into another function (the button command). I've tried the IDLE debugging but it seems to freeze on me!
I presume you want the main window to remain when one selects a particular game. That means that the game should be in a separate frame, initially in a separate Toplevel. Modify your rps file something like the following,
from tkinter import *
from tkinter.ttk import *
import random
class RPS(Toplevel):
def __init__(self, parent, title):
Toplevel.__init__(parent)
self.title(title)
#game code goes in here, including other functions
# more code to define what this looks like
# including a Frame, buttons, labels, etc>
if __name__=='__main__':
root=Tk()
root.withdraw()
RPS(title = "Rock, Paper, Scissors")
root.mainloop()
This way, importing the file does not create a second root and mainloop.
If you want only one game running at a time, you could instead use a paned window with two panes. Turtledemo does this. The code is in turtledemo.main. You would then derive RPS from Frame and pack it into the second pane.

How do I run a program within a Tkinter frame?

I'm trying to create a Tkinter app that incorporates the use of a touchscreen keyboard and will be run off a Raspberry Pi. I found an onscreen keyboard called Matchbox-keyboard.
My question is: is there a way to "embed" this keyboard into a GUI created by Tkinter? I would like to embed the keyboard so it opens at the bottom of the parent window.
So far all I can come up with is:
subprocess.Popen(['matchbox-keyboard'])
which works, but it opens in a separate window.
Below is a sample of my code. Keep in mind that I haven't coded the get() functions for the text fields yet, or any of the other functions for that matter.
from tkinter import *
from tkinter import ttk
import subprocess
process_one = subprocess.Popen(['matchbox-keyboard'])
root = Tk()
bottomframe = Frame(root)
bottomframe.pack(side = BOTTOM)
root.title("PinScore")
L0 = Label(root, text = "Welcome to PinScore!")
L0.pack(side = TOP)
L1 = Label(root, text = "Initials:")
L1.pack(side = LEFT)
E1 = Entry(root, bd = 5)
E1.pack(side = RIGHT)
L2 = Label(root, text = "High Score:")
L2.pack( side = RIGHT)
E2 = Entry(root, bd = 5)
E2.pack(side = RIGHT)
B = Button(bottomframe, text = "Enter High Score")
B.pack(side = BOTTOM)
root.mainloop()
The short answer: no, but there is hope, and it will require a fair amount of work. According to the github it is made in gtk. Then the question becomes "Can I put a gtk object in my tkinter program?". To my knowledge (and a lot of Googling) there is no way to embed gtk features in the Tkinter. You may want to try pyGTK instead, because these would be much easier to integrate (I know that it is possible). I might suggest that before you get any further in your project.
Use PyGTK! The github contains the gtk source and you can do it that way.
Actually, looking more at the github, you may not need to do that. The keyboard allows for command-line options, such as -v,--override Absolute positioning on the screen and -g,--geometry <HxW.y.x> Specify keyboard's geometry (taken from the github). You won't be able to control the z position (as in whether it is above or below your window).
If you truely want the embeded feeling, the github also says that you can embed it in gtk and points to examples/matchbox-keyboard-gtk-embed.c this might be what your looking for. You probably can translate it to pygtk. I found this, which talks about XEMBED. And I found this too which actually embeds something. Finally, I'll point you to the docs for gtk.socket.

Categories