How could I use the winsound.PlaySound() function to play with a variable stored instead of a specific sound? I am making a makeshift Music Player and I want to be able to simply play a song that is selected by the user. Here's my current code.
import Tkinter, Tkconstants, tkFileDialog
import winsound
from Tkconstants import *
from tkFileDialog import *
from PIL import Image, ImageTk
class MusicPlayer(Tkinter.Frame):
def __init__(self, root):
Tkinter.Frame.__init__(self, root)
# options for buttons
button_opt = {'fill': Tkconstants.BOTH, 'padx': 5, 'pady': 5}
#options for images
# define image
img = Image.open('musicPlayer.PNG')
bg = ImageTk.PhotoImage(img)
label = Tkinter.Label(image=bg)
label.image = bg
label.pack()
# define buttons
but1 = Tkinter.Button(self, text='Play', command=self.play)
but2 = Tkinter.Button(self, text='Stop', command=self.stop)
but1.grid(sticky="S, W, E", column=1)
but1.grid(sticky="S, W, E", column=1)
# define options for opening or saving a file
self.file_opt = options = {}
options['defaultextension'] = '*.wav'
options['filetypes'] = [('WAV Sound Files', '*.wav')]
options['initialdir'] = 'C:\\'
options['initialfile'] = '.wav'
options['parent'] = root
options['title'] = 'Pick a File'
# This is only available on the Macintosh, and only when Navigation Services are installed.
#options['message'] = 'message'
# if you use the multiple file version of the module functions this option is set automatically.
#options['multiple'] = 1
# defining options for opening a directory
self.dir_opt = options = {}
options['initialdir'] = 'C:\\'
options['mustexist'] = False
options['parent'] = root
options['title'] = 'Pick a Dir'
def askopenfile(self):
return tkFileDialog.askopenfile(mode='r', **self.file_opt)
def askopenfilename(self):
# get filename
filename = tkFileDialog.askopenfilename(**self.file_opt)
# open file on your own
if filename:
return open(filename, 'r')
print filename
def asksaveasfile(self):
return tkFileDialog.asksaveasfile(mode='w', **self.file_opt)
def asksaveasfilename(self):
# get filename
filename = tkFileDialog.asksaveasfilename(**self.file_opt)
# open file on your own
if filename:
return open(filename, 'w')
def askdirectory(self):
return tkFileDialog.askdirectory(**self.dir_opt)
def play(self):
soundfile = self.askopenfilename()
winsound.PlaySound(soundfile, winsound.SND_FILENAME)
def stop(self):
winsound.PlaySound(None, winsound.SND_PURGE)
if __name__=='__main__':
root = Tkinter.Tk()
root.iconbitmap(r'C:\Python27\DLLs\musicPlayer.ico')
MusicPlayer(root).pack()
root.wm_title('Music Player')
root.mainloop()
Things to Note
I am new to the winsound plugin, as well as Python itself, and I am not sure which flag I am supposed to use.
Error I get
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Python27\lib\lib-tk\Tkinter.py", line 1532, in __call__
return self.func(*args)
File "C:\Users\Brenneman.Josh.19\Downloads\code (2)\MusicPlayer.py", line 88, in play
winsound.PlaySound(soundfile, winsound.SND_FILENAME)
TypeError: must be string or read-only buffer, not file
winsound's PlaySound() needs to be passed a string with the filename and one or more flags. I'd recommend the SND_ASYNC flag, which plays the sound and returns immediately. Use the following:
winsound.PlaySound('C:/Windows/Media/chimes.wav', winsound.SND_ASYNC)
Related
I try to make a function, when user type the file name in inputField and click the save button. The mdb file can be copied with new Entry name, and the message will show source => destination. Turning to the same file name, it will show File has existed. But when I type the new file name, click the save button. It always show File has existed. I can't figure out what's wrong with my code.
from tkinter.ttk import *
class View(Frame):
def __init__(self, master=None):
Frame.__init__(self, master)
self.winfo_toplevel().title("Save File")
self.grid()
self.init_view()
def init_view(self):
self.inputText = Label(self)
self.inputText["text"] = "Input Serial ID"
self.inputText.grid(row=0, column=0, sticky=N + E)
self.inputField = Entry(self)
self.inputField["width"] = 20
self.inputField.grid(row=0, column=1, sticky=N + W)
self.save = Button(self)
self.save["text"] = "Save"
self.save.grid(row=1, column=1, sticky=N + W)
self.displayText = Label(self)
self.displayText["text"] = "Status:Idle"
self.displayText.grid(row=3, column=0, columnspan=7, sticky=N)
if __name__ == '__main__':
root = Tk()
app = View(master=root)
root.mainloop()
import shutil
import sys
from datetime import datetime
from Save_Server_View import View
from tkinter import Tk
year = datetime.now().year
month = datetime.now().month
src = r"HIDE FOR PRI"
dir = os.path.dirname(os.path.realpath('__file__'))
dst = os.path.join(dir, ".\\data\\" + str(year) + "\\" + str(month))
# Controller
class Controller:
def __init__(self):
self.app = View(master=Tk())
self.app.save["command"] = self.save_method
self.app.mainloop()
# Copy & Rename File
def save_method(self):
for root, dirs, files in os.walk(src):
for filename in files:
if not os.path.exists(os.path.join(dst)):
message = (os.path.join(dst)), "not found"
self.app.displayText["text"] = message
else:
first_src_file_path = os.path.join(src, '', filename)
new_dst_file_path = os.path.join(dst, '', self.app.inputField.get() + '.mdb')
new_dst_file_name = os.path.basename(new_dst_file_path)
try:
if not os.path.exists(os.path.join(dst, new_dst_file_name)):
shutil.copy(first_src_file_path, new_dst_file_path)
message = 'source={} => destination={}'.format(src, dst)
self.app.displayText["text"] = message
except:
message = "Unexpected error:", sys.exc_info()[0]
self.app.displayText["text"] = message
else:
self.app.displayText["text"] = 'File has existed.'
# Execute
if __name__ == '__main__':
app = Controller()
I except the message can be showed correct when file(with new name) copied to the destination file path. Then show 'source={} => destination={}'.format(src, dst)'. When the filename was same in the destination file path, it will show 'File has existed.'
Update the src contents when you click save button.
Just add the following line before the for loop in your save_methodfunction.
src = self.app.inputField.get()
I am trying to write a GUI that can display the log file in real time (tail -f log). The new line from the log file can be printed out into the terminal, but it cannot be loaded into the text field (line #). Can any one tell me why it won't put back to the text field?
from Tkinter import *
import os, time
import tkFileDialog
class Controller(object):
def __init__(self, master):
""" Main interface:
master - the top level window
"""
self._master = master
frame1 = Frame(self._master)
label = Label(self._master, text="Select a Log File")
label.pack(side=TOP)
currentLogfile = StringVar(self._master)
LogfileList = [f for f in os.listdir('.') if os.path.isfile(f)]
currentLogfile.set(LogfileList[0])
chooseLog = OptionMenu(self._master, currentLogfile, *LogfileList, command = self.file_open)
chooseLog.config(width = "300")
chooseLog.pack(side=TOP)
self._master.config(menu=chooseLog)
self._Text=Text(frame1, bg = 'black', fg = 'white')
self._Text.pack(side = TOP,fill=BOTH, expand = True,pady=20)
w = Scrollbar(self._Text)
w.pack(side=RIGHT, fill=Y)
frame1.pack(side=TOP, fill=BOTH, padx=5,expand=True)
def file_open(self,filename):
#clear text field
self._Text.delete('1.0', END)
with open(filename,'r') as f:
loglines = follow(f)
for line in loglines:
#print line
self._Text.insert(END,line)
def follow(thefile):
thefile.seek(0,2)
while True:
line = thefile.readline()
if not line:
time.sleep(5)
continue
yield line
if __name__ == "__main__":
root=Tk()
c=Controller(root)
root.title("log")
root.geometry("750x500")
root.mainloop()
Most of the code below is just so the problem is accurately replicated, the issue most likely is in the hand-off of filename fromaskopenfilenameI() to printing(stringToPrint)or the if statement at the end.
Goal
The goal of this program is to simply print the file path to the console when Print File Path button is clicked.
Current state
When the program is executed the window appears correctly and the it lets you select a file in the file system. Once the file is opened, the script seems to call printing method before it executes its own print statement. When I open another file it prints the only the print statement from askopenfilename() (which is correct).
However, clicking the Print File Path Button does not seem to get work at any stage.
An example output would be:
Value on click: no-file
askopenfilename value: C:/Temp/AFTER_FIRST_OPEN.txt
askopenfilename value: C:/Temp/AFTER_SECOND_OPEN.txt
Code
import Tkinter, Tkconstants, tkFileDialog
filename = 'no-file'
class TkApp(Tkinter.Frame):
def __init__(self, root):
Tkinter.Frame.__init__(self, root)
# options for buttons
button_opt = {'fill': Tkconstants.BOTH, 'padx': 5, 'pady': 5}
# define buttons
Tkinter.Button(self, text='Open File', command=self.askopenfilename).pack(**button_opt)
Tkinter.Button(self, text='Print File Path', command=self.printing(filename)).pack(**button_opt)
Tkinter.Button(self, text='Quit', command=self.quit).pack(**button_opt)
# define options for opening or saving a file
self.file_opt = options = {}
options['defaultextension'] = '.twb'
options['filetypes'] = [('All', '*')]
options['initialdir'] = 'C:\\'
options['parent'] = root
options['title'] = 'Select a File'
def askopenfilename(self):
"""Returns an opened file in read mode.
This time the dialog just returns a filename and the file is opened by your own code.
"""
global filename
# get filename
filename = tkFileDialog.askopenfilename(**self.file_opt)
# open file on your own
if filename:
print "askopenfilename value: " + filename
return filename
def printing(self, stringToPrint):
print "Value on click: " + stringToPrint
def quit(self):
root.destroy()
if __name__=='__main__':
root = Tkinter.Tk()
root.title("Path Printer")
TkApp(root).pack()
root.mainloop()
The root of your problem is that you're calling self.printing at the time you create the button. The solution is simple: change self.printing(filename) to be just self.printing, and then have self.printing print an attribute that is set by self.askopenfilename.
For example:
class TkApp(Tkinter.Frame):
def __init__(self, root):
...
self.currentFile = None
...
Tkinter.Button(self, text='Open File', command=self.askopenfilename)
Tkinter.Button(self, text='Print File Path', command=self.printing)
...
def askopenfilename(self):
...
self.currentFile = tkFileDialog.askopenfilename(**self.file_opt)
...
def printing(self):
print "Value on click: " + self.currentFile
Note: a return statement in a function that is called from a button serves absolutely no purpose. The actual caller of the button ignores all return values.
I think the problem is that the self.printing function cannot take arguments when called from a button press. This is common in many GUI libraries. To get around this, I would recommend that you change filename to self.filename, so that it can be called from self.printing even if it isn't passed.
The code would be:
import Tkinter, Tkconstants, tkFileDialog
class TkApp(Tkinter.Frame):
def __init__(self, root):
Tkinter.Frame.__init__(self, root)
# options for buttons
button_opt = {'fill': Tkconstants.BOTH, 'padx': 5, 'pady': 5}
#moved initiation of filename to here so it will print if no file has been selected
self.filename = 'no-file'
# define buttons
Tkinter.Button(self, text='Open File', command=self.askopenfilename).pack(**button_opt)
Tkinter.Button(self, text='Print File Path', command=self.printing).pack(**button_opt) #not the removal of variable.
Tkinter.Button(self, text='Quit', command=self.quit).pack(**button_opt)
# define options for opening or saving a file
self.file_opt = options = {}
options['defaultextension'] = '.twb'
options['filetypes'] = [('All', '*')]
options['initialdir'] = 'C:\\'
options['parent'] = root
options['title'] = 'Select a File'
def askopenfilename(self):
"""Returns an opened file in read mode.
This time the dialog just returns a filename and the file is opened by your own code.
"""
# get filename - edited to be part of self
self.filename = tkFileDialog.askopenfilename(**self.file_opt)
# open file on your own
if self.filename:
print "askopenfilename value: " + self.filename
return self.filename
def printing(self):
print "Value on click: " + self.filename
def quit(self):
root.destroy()
if __name__=='__main__':
root = Tkinter.Tk()
root.title("Path Printer")
TkApp(root).pack()
root.mainloop()
I am building a text editor like Notepad in python and i am using Tkinter.
I have implemented New, Open, Save as, Quit,Cut, Copy, Paste, About and Help functions of the editor successfully. But I'm struggling with the Save function.
When I open a previously saved file and save it after editing it is functioning like Save as function. I have used tkFileDialog.asksavefile to save the text file and tkFileDialog.asksavefilename to implement the Save as function of the editor.
I am very new to python.
Can anyone guide me here ?
#! /usr/bin/python
import Tkinter
from Tkinter import *
import tkFileDialog, tkMessageBox
import os
class OpenEdit:
def __init__(self):
# Root Frame widget
self.root = Tk()
# Menu panel in frame
menubar = Menu(self.root)
# File menu,for open,save,save as and quit
filemenu = Menu(menubar)
editmenu = Menu(menubar)
filemenu.add_command(label="New", command=self.new)
filemenu.add_command(label="Open", command=self.open)
filemenu.add_command(label="Save", command=self.save)
filemenu.add_command(label="Save as", command=self.save_as)
filemenu.add_separator()
filemenu.add_command(label="Quit", command=self.root.quit)
menubar.add_cascade(label="File", menu=filemenu)
#Edit menu including Cut, Copy and Paste
editmenu = Menu(menubar)
editmenu.add_command(label="Cut", command=self.cut)
editmenu.add_command(label="copy", command=self.copy)
editmenu.add_command(label="Paste", command=self.paste)
menubar.add_cascade(label="Edit", menu=editmenu)
# About menu for show about us and help
aboutmenu = Menu(menubar)
aboutmenu.add_command(label="About", command=self.about)
aboutmenu.add_command(label="Help", command=self.help)
menubar.add_cascade(label="About", menu=aboutmenu)
# Returning defined setting for GUI
self.root.config(menu=menubar)
#Setting up the title of the widget
self.root.title("Untitled - OpenEdit")
# Adding Text Widget in the GUI
self.text = Text(self.root)
# This line allows it to be resized
self.text.pack(expand=YES, fill=BOTH)
self.root.mainloop()
#Defining new method
def new(self):
self.root.title("Untitled - OpenEdit")
self.file = None
self.text.delete(1.0,END)
#Defining open method
def open(self):
self.file = tkFileDialog.askopenfilename(defaultextension=".txt",filetypes=[("All Files","*.*"),("Text Documents","*.txt")])
if self.file == "":
#no file to open
self.file = None
else:
#try to open the file
#set the window title
self.root.title(os.path.basename(self.file) + " - OpenEdit")
self.text.delete(1.0,END)
file = open(self.file,"r")
self.text.insert(1.0,file.read())
file.close()
#Defining save method
def save(self):
fileName = tkFileDialog.asksaveasfile(mode='w')
try:
file = open(fileName, 'w')
textoutput = self.text.get(0.0, END)
file.write(textoutput)
except:
pass
finally:
file.close()
#Defining save_as method
def save_as(self):
fileName = tkFileDialog.asksaveasfilename(initialfile='Untitled.txt',defaultextension=".txt",filetypes=[("All Files","*.*"),("Text Documents","*.txt")])
try:
file = open(fileName, 'w')
textoutput = self.text.get(0.0, END)
file.write(textoutput)
except:
pass
finally:
file.close()
#Defining cut method
def cut(self):
self.text.event_generate("<<Cut>>")
#Defining copy method
def copy(self):
self.text.event_generate("<<Copy>>")
#Defining paste method
def paste(self):
self.text.event_generate("<<Paste>>")
#Defining about method
def about(self):
tkMessageBox.showinfo("OpenEdit","Created by: XYZ")
#Defining help method
def help(self):
tkMessageBox.showinfo("Help","This is help")
#Starting the instance of the class OpenEdit
OpenEdit()
Your save function explicitly prompts for a filename. If you don't want to prompt for a filename, just don't do that.
Instead, use the current filename ... I see open already saves it:
def open(self):
self.file = tkFileDialog.askopenfilename(...
so you can re-use it in save:
def save(self):
# filename = tkFileDialog.asksaveasfile(...
fileName = self.file
I have this code in python 2.7 using tkinter that creates a Button on a Frame to open a file. There's a Label under it. I'm trying to make it so once the file is opened, the label prints the path, "file1.name" or whatever, on the Label, and if you open a new file it will change that Label again.
Also, I'm betting there's a better way to move data between the functions than I'm using here with global, but that's not worrying me right now.
I have to move the data from the opened files between functions so that I can mix the data and save to a new file. The code is:
from Tkinter import *
import Tkinter
import tkFileDialog
import tkMessageBox
root = Tkinter.Tk()
global rfile1
global rfile2
rfile1 = ""
rfile2 = ""
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.grid()
self.createWidgets1()
self.createLabels1()
self.createWidgets2()
self.createLabels2()
def createWidgets1(self):
self.oButton = Button(self, text = "open1", command = self.openfile1)
self.oButton.grid()
def createLabels1(self):
self.oLabel = Label(self, text = "whoops")
self.oLabel.grid()
def createWidgets2(self):
self.oButton = Button(self, text = "open2", command= self.openfile2)
self.oButton.grid()
def createLabels2(self):
self.oLabel2 = Label(self, text = "whoops2")
self.oLabel2.grid()
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
rfile1 = file1.read()
tkMessageBox.showinfo("oy", rfile1, parent=root)
def openfile2(self):
file2 = tkFileDialog.askopenfile(parent=root, mode='rb')
rfile2 = file2.read()
tkMessageBox.showinfo("hola", rfile2, parent=root)
app = Application()
app.master.title("whiggy whompus")
app.mainloop()
If I understand correctly, you want something like (untested):
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
self.oLabel.configure(text=file1.name)
rfile1 = file1.read()
tkMessageBox.showinfo("oy", rfile1, parent=root)
#mgilson has solved your first question. Your second question, about how to pass parameters between functions without using globals :
you might want to look at storing the variables as attributes on your application class :
The syntax self. is an attribute on the current instance (an instance being a particular example of a class - just like your car is a specific example of a class "car").
You can use instance attributes in this example as if they are globals.
from Tkinter import *
import Tkinter
import tkFileDialog
import tkMessageBox
root = Tkinter.Tk()
class Application(Frame):
def __init__(self, master = None):
Frame.__init__(self, master)
self.grid()
self.createWidgets1()
self.createLabels1()
self.createWidgets2()
self.createLabels2()
self.rfile1 = ""
self.rfile2 = ""
def createWidgets1(self):
self.oButton = Button(self, text = "open1", command = self.openfile1)
self.oButton.grid()
def createLabels1(self):
self.oLabel = Label(self, text = "whoops")
self.oLabel.grid()
def createWidgets2(self):
self.oButton = Button(self, text = "open2", command= self.openfile2)
self.oButton.grid()
def createLabels2(self):
self.oLabel2 = Label(self, text = "whoops2")
self.oLabel2.grid()
def openfile1(self):
file1 = tkFileDialog.askopenfile(title = "choose a file, *****", parent=root, mode = 'rb')
self.rfile1 = file1.read()
tkMessageBox.showinfo("oy", self.rfile1, parent=root)
def openfile2(self):
file2 = tkFileDialog.askopenfile(parent=root, mode='rb')
self.rfile2 = file2.read()
tkMessageBox.showinfo("hola", self.rfile2, parent=root)
app = Application()
app.master.title("whiggy whompus")
app.mainloop()