I can't Manage to close from in Python 3 with tkinter - python

I am trying to build a xml parser in python, i start to build gui framework, and here i need to create some forms to save some settings values. I manage to make it work and save some values to txt files for startup. But what ever i tried i can't manage to close the settings form when i click button. i need to close it with the x on the window. i can't find the root of the issue.
what i am trying to do is, when i click Cancel, form will be closed. if i click Save, form will first save data then close.
thanks a lot for your supports.
my code is as follows:
try:
# for Python2
print ("Importing for py2");
from Tkinter import * ## notice capitalized T in Tkinter
import tkFileDialog
except ImportError:
# for Python3
print ("Importing for py2 Failed !!!!");
print ("Importing for py3");
from tkinter import *
from tkinter import filedialog
from tkinter.scrolledtext import ScrolledText
from tkinter import messagebox
mainform = Tk()
mainform.minsize(300,100)
mainform.geometry('{}x{}'.format(800, 600))
mainform.title("OVF Template Parser - By Gurhan Cagin (R) 2018")
textPad = ScrolledText(mainform, width=100, height=80)
textPad.pack()
## functions and procdures
def donothing():
x = 0
def quit():
if messagebox.askokcancel("Quit", "Do you really want to quit?"):
exit()
def about_command():
label = messagebox.showinfo("About", "Nokia OVF Template Parser \nCopyright 2018 \nNo rights left to reserve")
def open_command():
file = filedialog.askopenfile(parent=mainform, mode='rb', title='Select a file')
if file != None:
contents = file.read()
textPad.insert('1.0',contents)
file.close()
def SettingsFormFxn():
settingsForm = Tk()
settingsForm.minsize(300,100)
settingsForm.geometry('{}x{}'.format(750, 550))
settingsForm.title("Settings for the devault values")
## Frames
top_frame = Frame(settingsForm, width = 740, height = 50, pady = 3)
bottom_frame = Frame(settingsForm, width = 740, height = 50, pady = 3)
settingsForm.grid_rowconfigure(1, weight=1)
settingsForm.grid_columnconfigure(0, weight=1)
top_frame.grid(row=0, sticky="ew")
bottom_frame.grid(row = 4, sticky = "e")
b1 = Label(top_frame, text = "CPU per Core in Ghz:")
b1.grid(row = 0, column = 0)
entryText = StringVar(settingsForm, "2.1")
e1 = Entry(top_frame, textvariable = entryText, width = 5)
e1.grid(row = 0, column = 2)
def SaveFxn():
with open("settings.txt", "w") as f:
f.write(e1.get() + "\n")
##f.write(ent2.get() + "\n")
def CancelFxn():
settingsForm.destroy
cancel = Button(bottom_frame, text = "Cancel", command = CancelFxn, pady = 10, padx = 10,activebackground='grey',activeforeground='#AB78F1',bg='#e87474',highlightcolor='red')
cancel.grid(row = 0, column = 10)
save = Button(bottom_frame, text = "Save", command = SaveFxn, pady = 10, padx = 10)
save.grid(row = 0, column = 11)
settingsForm.mainloop()
## EOF FXNS
## Menu Definitions
menubar = Menu(mainform)
## File Menu
filemenu = Menu(menubar, tearoff = 0)
filemenu.add_command(label = "Open", command = open_command)
filemenu.add_separator()
filemenu.add_command(label="Exit", command = quit)
menubar.add_cascade(label="File", menu=filemenu)
## Settings Menu
settingsmenu = Menu(menubar, tearoff = 0)
settingsmenu.add_command(label = "Settings", command = SettingsFormFxn)
menubar.add_cascade(label="Settings",menu=settingsmenu)
## About Menu
aboutmenu = Menu(menubar, tearoff = 0)
aboutmenu.add_command(label = "About", command = about_command)
menubar.add_cascade(label="Help", menu=aboutmenu)
mainform.config(menu=menubar)
## EOF Menu Definitions
## Main loop
mainloop()

You forgot your parenthesis when trying to call settingsForm.destroy.
def CancelFxn():
settingsForm.destroy()

Related

Clearing a tkinter root.subform from within a separate function

I have several larger tkinter / python program which I would like to incorporate into one program which would clear a frame when another program is called; each program currently being inside a function (I probably should use classes eventually when I understand them) and each of these function being displayed on a form being cleared of widgets from the previous if any do exist.
The code below is just a small trial for me to understand how to do this, but it's not working.
When I invoke the widget.destroy() function, it removes the frame (DisplayFrame) and does not clear the widgets inside it and hence not displaying the new widgets.
here is the current trial code:
#!/usr/bin/env python3
import tkinter as tk
from tkinter import *
from tkinter import ttk
#import pandas as pd
import MultiTempsP3
import datetime, time
from tkinter import messagebox
import sqlite3
from tkinter import colorchooser
from configparser import ConfigParser
import os
import csv
if os.environ.get('DISPLAY','') == "":
print('no display found.Using :0.0')
os.environ.__setitem__('DISPLAY',':0.0')
root = tk.Tk()
root.title("Kombucha Program")
root.geometry("1400x800")
root.minsize(width=900, height=600)
#root.maxsize(width=1400, height = 900)
root.grid_rowconfigure(3, weight=1)
root.grid_columnconfigure(2, weight=1)
root.configure( bg = '#000080' )
DisplayFrame = tk.Frame(root, width=1200, height = 630, bg = 'yellow') #0059b3')
DisplayFrame.grid(column=0,row=1, sticky = N, in_ = root)
rightFrame = tk.Frame(root, width = 120, height = 390, bg = 'white') # #000080
rightFrame.grid(column = 1, row = 0, pady = 10, padx = 10)
lblFrame = tk.Frame(root, height = 70, width = 670, bg = 'black')
lblFrame.grid(column = 0, row = 0, sticky =N, in_ = root)
##'W' stands for West = WrightFrmae (west fframe on the right of screen
#WrightFrame = tk.Frame(rightFrame, width = 70, height = 300, bg = 'green') # #000080
#WrightFrame.grid(column = 0, row = 1)
WidgetFrame = tk.Frame(root, height = 300, width = 120, bg = 'red') # #000080
WidgetFrame.grid(column=0,row=2, pady = 30)
fromTemp = MultiTempsP3.temps("65cd6bd")
lblTemp = Label(rightFrame, text=fromTemp).grid(row=1,column=0,pady=0 )
#lblTemp.pack()
def clearDisplayFrame():
for widgets in DisplayFrame.winfo_children():
widgets.destroy()
###***### - This section is in the right top little frame = rightFrame
state = "yes" ## delete this row and use below state=GPIO when on an RPi
#state = GPIO.input(17)
if state:
state_17="GPIO_17 (HeatPad) is On "
else:
state_17="GPIO_17 (HeatPad) is Off "
lblHeatPad = Label(rightFrame, text=state).grid(row=3,column=0,pady=0 ) #shows as text in the window
#lblHeatPad.pack() #organizes widgets in blocks before placing them in the parent.
###***### End of rightFrame widgets
def func_quit():
root.destroy()
def openData():
clearDisplayFrame()
print("I am inside openData()")
lbltrial=tk.Label(DisplayFrame,text="trial").grid(row=3, column=2)
def func_Temps():
clearDisplayFrame()
print("I am inside func_Temps()")
#DisplayFrame = tk.Frame(root, width=1200, height = 630, bg = 'yellow') #0059b3')
#DisplayFrame.grid(column=0,row=1, sticky = N, in_ = root)
lblSomething = tk.Label(DisplayFrame, text = "Open Temps").grid(row=2,column=2)
###***### This section is top of left = lblFrame
exitButton = tk.Button(lblFrame, text="Quit the Program", width = 12, command=root.destroy, bg= "magenta")
exitButton.grid(row = 0, column = 0, columnspan = 1, pady = 5, padx = 5)
dataButton = Button(lblFrame, text="Open Dates Window", command=openData).grid(row=0, column=1) ## the open refers to the above function
tempsButton= Button(lblFrame, text="Open Temps Info", command=func_Temps).grid(row=0, column=2)
###***### End of top left widget in lblFrame
mainloop()
As an answer, here is an approach that uses 2 frame and switches between them in the click of the switch. This is the way usually switching between frame is implemented in procedural programming, AFAIK:
from tkinter import *
root = Tk()
def change(frame):
frame.tkraise() # Raising the passed frame
window1 = Frame(root)
window2 = Frame(root)
window1.grid(row=0,column=0) # Grid in the same location so one will cover/hide the other
window2.grid(row=0,column=0)
# Contents inside your frame...
Label(window1,text='This is page 1',font=(0,21)).pack()
Label(window2,text='This is page 2',font=(0,21)).pack()
# Buttons to switch between frame by passing the frame as an argument
Button(root,text='Page 1',command=lambda: change(window1)).grid(row=1,column=0,stick='w')
Button(root,text='Page 2',command=lambda: change(window2)).grid(row=1,column=0,stick='e')
root.mainloop()
So instead of destroying all the items inside your frame, you should just raise the other frame, as destroyed widgets cannot be brought back.

Making executable cx_freeze with pywin32 code = error no module named win32

So I have this PDF printer code (the code runs from console perfectly) and I wanted to make it executable .exe.
I tried with Python 3.8.2, cx_freeze, by issuing the cxfreeze-quickstart.exe command. Filling basic data, and selecting (G) as GUI option. All went well and got the program pdfprinter.exe, but when I try to run it on Windows 10, i get error message "no module named win32".
Can someone help how to make an executable from this code?
Error message picture
import win32api
import win32print
import traceback
from tkinter.filedialog import askopenfilename
from tkinter import *
from tkinter import font # * doesn't import font or messagebox
from tkinter import messagebox
root = Tk()
root.title("Python Printer")
root.geometry("410x310")
root.resizable(False, False)
root.tk.call('encoding', 'system', 'utf-8')
def font_size(fs):
return font.Font(family='Helvetica', size=fs, weight='bold')
# Add a grid
mainframe = Frame(root)
#mainframe.grid(column=0,row=0, sticky=(N,W,E,S) )
mainframe.grid(column=0,row=0, sticky=(N) )
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 10, padx = 0)
# Create a _printer variable
_printer = StringVar(root)
# Create a _color variable
_color = StringVar(root)
_filename = ""
# on change dropdown value
def sel_printer(*args):
print( _printer.get() )
# link function to change dropdown
_printer.trace('w', sel_printer)
def sel_color(*args):
print( _color.get() )
# link function to change dropdown
_color.trace('w', sel_color)
def UploadAction(event=None):
global _filename
_filename = filedialog.askopenfilename()
#print('Selected:', _filename)
def PrintAction(event=None):
PRINTER_DEFAULTS = {"DesiredAccess":win32print.PRINTER_ALL_ACCESS}
pHandle = win32print.OpenPrinter(_printer.get(), PRINTER_DEFAULTS)
properties = win32print.GetPrinter(pHandle, 2)
properties['pDevMode'].Color = 1 if str(_color.get()) == "Color" else 2
properties['pDevMode'].Copies = 1
win32print.SetPrinter(pHandle, 2, properties, 0)
if not _filename:
messagebox.showerror("Error", "No File Selected")
return
elif not _printer.get():
messagebox.showerror("Error", "No Printer Selected")
return
try:
#win32print.SetDefaultPrinter(_printer.get())
win32api.ShellExecute(0, "print", _filename, None, ".", 0)
win32print.ClosePrinter(pHandle)
except:
pass
messagebox.showerror("Error", "There was an error printing the file :(")
choices = [printer[2] for printer in win32print.EnumPrinters(2)]
_printer.set(win32print.GetDefaultPrinter()) # set the default option
popupMenu = OptionMenu(mainframe, _printer, *choices)
popupMenu['font'] = font_size(12)
Label(mainframe, text="SELECT PRINTER").grid(row = 1, column = 1)
popupMenu.grid(row = 2, column =1)
# Dictionary with options
choices = ["COLOR", "MONOCHROME"]
_color.set("COLOR") # set the default option
popupMenu2 = OptionMenu(mainframe, _color, *choices)
popupMenu2['font'] = font_size(12)
Label(mainframe, text="COLOR MODE").grid(row = 3, column = 1)
popupMenu2.grid(row = 4, column =1)
Label(mainframe, text="SELECT FILE").grid(row = 5, column = 1)
button = Button(mainframe, text=u"\uD83D\uDCC1" ' BROWSE', command=UploadAction)
button['font'] = font_size(12)
button.grid(row = 6, column =1)
_copies = IntVar()
_copies.set(1)
def copies_increase(event=None):
_copies.set(_copies.get() + 1)
def copies_decrease(event=None):
_copies.set(_copies.get() - 1)
if _copies.get() < 1 :
_copies.set(1)
Label(mainframe, textvariable=_copies).grid(columnspan=2)
button_frame = Frame(mainframe)
button_frame.grid(columnspan=2)
dec_button = Button(button_frame, text=u"\u2212", command=copies_decrease, fg="dark green", bg = "white", height=1, width=3 )
dec_button['font'] = font_size(10)
inc_button = Button(button_frame, text=u"\uFF0B", command=copies_increase, fg="dark green", bg = "white", height=1, width=3 )
inc_button['font'] = font_size(10)
button_frame.columnconfigure(0, weight=1)
button_frame.columnconfigure(1, weight=1)
dec_button.grid(row=0, column=0, sticky=W+E)
inc_button.grid(row=0, column=1, sticky=W+E)
Label(mainframe).grid(row = 10, column = 1)
p_button = Button(mainframe, text=u'\uD83D\uDDB6' + " PRINT", command=PrintAction, fg="dark green", bg = "white")
p_button['font'] = font_size(18)
p_button.grid(row = 11, column =1)
root.mainloop()

How to display tab widget after a toolbar menu in Python?

I am new to this tkinter menu. I am trying to upload and display an excel file by using the 'filemenu' in the menubar and 'btnNew' in the toolbar menu.
The application did run but it does not display my excel file after I browse the file. The application only display the datatypes of each variable in the excel file.
import pandas as pd
import xlrd
import tkinter as tk
from tkinter import Frame, Menu, Button, Label, Canvas
from tkinter import LEFT, RIGHT, TOP, BOTTOM, X, FLAT, RAISED
from tkinter import filedialog
from tkinter import ttk
root = tk.Tk() #main method 1 - create main window (parent window)
root.title("Data Visualisation")
width = 1000
height = 500
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
x = (screen_width / 2) - (width / 2)
y = (screen_height / 2) - (height / 2)
root.geometry('%dx%d+%d+%d' % (width, height, x, y))
root.resizable(1,1)
def browseFile():
global workbook, copyWorkbook, excel_file, sheetName, worksheet
fileName = filedialog.askopenfilename(initialdir = '/', title = 'New File', filetypes = (('excel file', '.xlsx'), ('excel file', '.xls'), ('all files', '*.*')))
excel_file = pd.ExcelFile(fileName)
workbook = xlrd.open_workbook(fileName)
sheetCount = workbook.nsheets
#Create tabs
sheetName = []
tab = []
for x in range(workbook.nsheets):
tab.append(ttk.Frame(tabControl))
sheetName = workbook.sheet_names()
tabControl.add(tab[x], text = sheetName[x])
df_table = excel_file.parse(sheetName[x])
print(df_table.dtypes)
lblTable = Label(tab[x], text = df_table.to_string(index = False)).grid()
btnGraph = Button(tab[x], text = "Graph").grid(sticky = 'w', column = 1, row = 5)
##MENU BAR
menubar = Menu(root)
root.config(menu = menubar)
#FILE MENU
filemenu = Menu(menubar, bg = '#BFBFBF', tearoff = 0)
menubar.add_cascade(label = 'File', menu = filemenu)
filemenu.add_command(label = 'New', compound = LEFT, command = browseFile)
filemenu.add_command(label = 'Open...', compound = LEFT)
filemenu.add_separator()
filemenu.add_command(label = 'Quit', compound = LEFT, command = root.quit)
#SEARCH MENU
searchmenu = Menu(menubar, bg = '#BFBFBF')
menubar.add_cascade(label = 'Search', menu = searchmenu)
searchmenu.add_command(label = 'Find...', compound = LEFT)
searchmenu.add_command(label = 'Replace...', compound = LEFT)
#HELP MENU
helpmenu = Menu(menubar, bg = '#BFBFBF')
menubar.add_cascade(label = 'Help', menu = helpmenu)
helpmenu.add_command(label = 'About', compound = LEFT)
##TOOLBAR MENU
toolbar = Frame(root, bd = 1, relief = RAISED)
#To browse excel file
btnNew = Button(toolbar, text = 'New', compound = TOP, relief = FLAT, activebackground = '#ADD8E6', padx = 20, pady = 2, command = browseFile).pack(side = LEFT)
btnOpen = Button(toolbar, text = 'Open', compound = TOP, relief = FLAT, activebackground = '#ADD8E6', padx = 10, pady = 2).pack(side = LEFT)
btnFind = Button(toolbar, text = 'Find', compound = TOP, relief = FLAT, activebackground = '#ADD8E6', padx = 10, pady = 2).pack(side = LEFT)
btnReplace = Button(toolbar, text = 'Replace', compound = TOP, relief = FLAT, activebackground = '#ADD8E6', padx = 10, pady = 2).pack(side = LEFT)
btnQuit = Button(toolbar, text = 'Quit', compound = TOP, relief = FLAT, activebackground = '#ADD8E6', padx = 10, pady = 2, command = root.quit).pack(side = RIGHT)
toolbar.pack(side = TOP, fill = X)
###Tab Widget
tabControl = ttk.Notebook(menubar)
tabHome = ttk.Frame(tabControl)
tabControl.add(tabHome, text = "Home")
#All the automation Tab is pack here
tabControl.pack(expand = 1, fill = 'both', side = LEFT)
root.mainloop() #main method 2 - run the application
The application should display tabs and in each tab, it should contain each sheet from the excel file. All the tabs must be display after the toolbar menu.
I'm not sure what is the problem as is does not specify if there is any error in my code.
All feedback is welcomed as I am trying to learn how to make a better interface using python. Thank you for your help :D
You set the wrong parent to the frame tabControl.
Change:
tabControl = ttk.Notebook(menubar)
to:
tabControl = ttk.Notebook(root)

Duplicate Frames Created When Calling a Function in a Tkinter Application

So this is my first Python GUI project utilizing tkinter. I come from a background in R.
I decided after a review of the documentation to create a class to handle the bulk of the work. The problem appears with my incrementer functions fwd() and bck(). If I do not call these functions in the following chunk of code:
class App:
def __init__(self, master):
....
self.total = 2
self.fwd()
self.bck()
The output of the entire code is an empty tkinter frame.
On the other hand, if I do call them, the fwd() function works as one would expect, but every time I click the back button (command = bck()), a new and identical GUI will be attached directly to the bottom of my current GUI. If I click the back button again, another GUI will pop up behind the current GUI.
from tkinter import *
from tkinter import font
from tkinter import filedialog
class App: #I'm not typing what goes in this class, this way I can avoid issues with App(Frame), etc. DUCKTYPE!
def __init__(self, master):
self.frame = Frame(master)
self.frame.pack()
self.master = master
master.title("PyCCI Caste")
self.total = 2
self.fwd() #Need to call these at the beginning otherwise the window is minimized??? No idea why.
self.bck() #The back button creates a duplicate window...
## +Incrementer
def fwd(self):
self.total += 1
print(self.total)
## -Incrementer THIS CREATES A SECOND PANED WINDOW, WHY?!
def bck(self):
self.total += -1
if self.total < 3:
self.total = 2
print(self.total)
#Body
self.k1 = PanedWindow(self.frame, #Note: if this is not self.frame, the error: 'App' object has no attribute 'tk' is thrown
height=500,
width=750,
orient = VERTICAL)
self.k1.pack(fill=BOTH, expand = 1)
self.titlefont = font.Font(size = 12,
weight = 'bold')
self.boldfont = font.Font(size=8,
weight = 'bold')
self.textfont = font.Font(family = 'Arial',
size = 10)
#Title
self.title = PanedWindow(self.k1)
self.k1.add(self.title, padx = 10, pady = 10)
Label(self.title, text = "Chronic Critically Ill Patient GUI",
font = self.titlefont,
fg="darkslateblue").pack()
#Top row open csv window & button
self.k2 = PanedWindow(self.k1)
self.k1.add(self.k2)
self.openbutton = Button(self.k2,
text = "Open CSV")#, command = openfile())
self.openbutton.pack(side = LEFT,
padx = 30)
#Panes below buttons
self.k3 = PanedWindow(self.k1)
self.k1.add(self.k3)
self.leftpane = PanedWindow(self.k3)
self.k3.add(self.leftpane,
width = 400,
padx = 30,
pady = 25,
stretch = "first")
self.separator = PanedWindow(self.k3,
relief = SUNKEN)
self.k3.add(self.separator,
width=2,
padx=1,
pady=20)
self.rightpane = PanedWindow(self.k3)
self.k3.add(self.rightpane,
width = 220,
padx = 10,
pady = 25,
stretch = "never")
#Left pane patient note text frame doo-diddly
self.ptframe = LabelFrame(self.leftpane,
text = "Medical Record",
font = self.boldfont,
padx = 0,
pady=0,
borderwidth = 0)
self.ptframe.pack()
Label(self.ptframe,
text = "patient # of ##").pack()
#Incrementer buttons
self.buttonframe = Frame(self.ptframe)
self.buttonframe.pack()
self.buttonframe.place(relx=0.97, anchor = NE)
#Back Button
self.button1 = Button(self.buttonframe, text = 'Back', width = 6, command = self.bck)
self.button1.grid(row = 0, column = 0, padx = 2, pady = 2)
#Next Button
self.button2 = Button(self.buttonframe, text = 'Next', width = 6, command = self.fwd)
self.button2.grid(row = 0, column = 2, padx = 2, pady = 2)
#Scrollbar!
self.ptscroll = Scrollbar(self.ptframe)
self.ptscroll.pack(side = RIGHT, fill = Y)
self.pttext = Text(self.ptframe,
height=300,
width=400,
wrap=WORD,
font=self.textfont,
spacing1=2,
spacing2=2,
spacing3=3,
padx=15,
pady=15)
self.pttext.pack()
self.ptscroll.config(command=self.pttext.yview)
self.pttext.config(yscrollcommand=self.ptscroll.set)
#Checkbuttons
self.checkframe = LabelFrame(self.rightpane, text="Indicators",
font=self.boldfont,
padx = 10,
pady = 10,
borderwidth=0)
self.checkframe.pack()
self.check1 = Checkbutton(self.checkframe, text="Non-Adherence")
self.check1.grid(row = 1,
column = 0,
sticky = W)
root = Tk()
app = App(root) ## apply the class "App" to Tk()
### Menu stuff does not need to be part of the class
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0)
filemenu.add_command(label="Open CSV")#, command=openfile)
menubar.add_cascade(label="File", menu=filemenu)
helpmenu = Menu(menubar, tearoff=0)
helpmenu.add_command(label="About")#, command=about)
menubar.add_cascade(label="Help", menu=helpmenu)
root.config(menu=menubar)
root.mainloop()
What do you folks think? If I'm missing any pertinent information here, please let me know. The difficulty I'm having is that I don't know what I don't know about Python/Tkinter yet.
Thanks, I really appreciate any insight and direction.
Solved (thanks Bryan Oakley & TigerhawkT3): Due to Python's use of indentation as part of its syntax, I had created a function bck() which, when called, includes the code for the entirety of the rest of the GUI. To solve this problem after it was pointed out, I drew heavily from:
Python def function: How do you specify the end of the function?
You appear you have a simple indentation error. It seems like you intend for bck to have four lines of code, but because almost all of the remaining code is indented the same, it is all considered to be part of bck.

music player playlist

i made a music player with a playlist but the songs in playlist are not playable because only the name of song is going in playlist not a complete mp3 file. can you tell me how to handle this problem??
here is my code:
from Tkinter import *
import mp3play
import tkFileDialog
import Tkinter
import tkFont
import Tkinter as tk
#from PIL import ImageTk,Image
def open_file(): #Opens a dialog box to open .mp3 file
global music #then sends filename to file_name_label.
global mp3
global play_list
filename.set (tkFileDialog.askopenfilename(defaultextension = ".mp3", filetypes=[("All Types", ".*"), ("MP3", ".mp3")]))
playlist = filename.get()
playlist_pieces = playlist.split("/")
play_list.set (playlist_pieces[-1])
playl = play_list.get()
play_list_display.insert(END, playl)
mp3 = filename.get()
print mp3
music = mp3play.load(mp3)
pieces = mp3.split("/")
name.set (pieces[-1])
def play(): #Plays the .mp3 file
music.play()
def stop(): #Stops the .mp3 file
music.stop()
def pause(): #Pauses or unpauses the .mp3 file
if music.ispaused() == True:
music.unpause()
elif music.ispaused() == False:
music.pause()
def vol(event): #Allows volume to be changed with the slider
v = Scale.get(volume_slider)
music.volume(v)
def tune_changed(event):
idx = event.widget.curselection()[0]
print ("Now playing %s" % event.widget.get(idx))
def Exit():
exit()
root = tk.Tk()
root.title("EmoPlayer")
root.configure(background='black')
#root = Tk()
root.geometry('300x100+750+300')
filename = Tkinter.StringVar()
name = Tkinter.StringVar()
play_list = Tkinter.StringVar()
menubar = Menu(root)
filemenu = Menu(menubar, tearoff=0, bg="black", fg="Orange")
menubar.add_cascade(label='File', menu = filemenu)
filemenu.add_command(label='Open', command = open_file)
filemenu.add_separator()
filemenu.add_command(label='Exit', command = Exit)
root.config(menu=menubar)
open_file = Button(root, width = 6, height = 1, text = 'Mood',fg='Orange', bg='black')
open_file.grid(row=0, column=3)
play_button = Button(root, width = 5, height = 1, text='Play', fg='Orange', command = play, bg="black")
play_button.grid(row=0, column=0, sticky = W)
stop_button = Button(root, width = 5, height = 1, text='Stop',fg='Orange', command = stop, bg="black")
stop_button.grid(row=0, column=1, sticky = W)
pause_button = Button(root, width = 5, height = 1, text='Pause',fg='Orange', command = pause, bg="black")
pause_button.grid(row=0, column=2)
volume_slider = Scale(root, label='Volume', orient = 'horizontal', fg = 'Orange', command = vol, bg="black")
volume_slider.grid(row=0, column=4)
file_name_label = Label(root, font=('Comic Sans', 8), fg = 'Orange', wraplength = 300, textvariable=name, bg="black" )
file_name_label.grid(row=3, column=0, columnspan=8)
play_list_window = Toplevel(root, height = 150, width = 100)
play_list_window.title("Playlist")
play_list_display = Listbox(play_list_window, selectmode=EXTENDED, width = 50, bg="Dark Slate grey", fg="Orange")
play_list_display.bind("<Double-Button-1>", tune_changed)
play_list_display.pack()
play_list_window.mainloop()
root.mainloop()
I had a look at your code because I haven't worked with mp3play before and thought it was interesting.
Here's what I changed:
I put your code in a class so that it's easier and cleaner to share variables between methods. It also removes the need to mess around with global. Generally cleaned up the code a bit, for example, breaking up excessively long lines. I tried not to change your code where it wasn't necessary though.
Added a trackLocations list that keeps the actual file paths.
Added a line that loads the new file on double clicking in the playlist
This was the result, I hope it helps:
from Tkinter import *
import mp3play
import tkFileDialog
import Tkinter
import tkFont
import Tkinter as tk
class musicplay:
def __init__(self):
self.music = None
self.play_list = []
self.trackLocations = []
self.root = tk.Tk()
self.root.title("EmoPlayer")
self.root.configure(background='black')
self.root.geometry('300x100+750+300')
self.filename = Tkinter.StringVar()
self.name = Tkinter.StringVar()
self.play_list = Tkinter.StringVar()
menubar = Menu(self.root)
filemenu = Menu(menubar, tearoff=0, bg="black", fg="Orange")
menubar.add_cascade(label='File', menu = filemenu)
filemenu.add_command(label='Open', command = self.open_file)
filemenu.add_separator()
filemenu.add_command(label='Exit', command = self.Exit)
self.root.config(menu=menubar)
open_file = Button(self.root, width = 6, height = 1,
text = 'Mood',fg='Orange', bg='black')
open_file.grid(row=0, column=3)
play_button = Button(self.root, width = 5, height = 1, text='Play',
fg='Orange', command = self.play, bg="black")
play_button.grid(row=0, column=0, sticky = W)
stop_button = Button(self.root, width = 5, height = 1, text='Stop',
fg='Orange', command = self.stop, bg="black")
stop_button.grid(row=0, column=1, sticky = W)
pause_button = Button(self.root, width = 5, height = 1, text='Pause',
fg='Orange', command = self.pause, bg="black")
pause_button.grid(row=0, column=2)
self.volume_slider = Scale(self.root, label='Volume',
orient = 'horizontal', fg = 'Orange',
command = self.vol, bg="black")
self.volume_slider.grid(row=0, column=4)
file_name_label = Label(self.root, font=('Comic Sans', 8),
fg = 'Orange', wraplength = 300,
textvariable=self.name, bg="black")
file_name_label.grid(row=3, column=0, columnspan=8)
play_list_window = Toplevel(self.root, height = 150, width = 100)
play_list_window.title("Playlist")
self.play_list_display = Listbox(play_list_window, selectmode=EXTENDED,
width = 50, bg="Dark Slate grey",
fg="Orange")
self.play_list_display.bind("<Double-Button-1>", self.tune_changed)
self.play_list_display.pack()
play_list_window.mainloop()
self.root.mainloop()
def open_file(self):
"""
Opens a dialog box to open .mp3 filemusic,
then sends filename to file_name_label.
"""
self.filename.set(tkFileDialog.askopenfilename(
defaultextension = ".mp3",
filetypes=[("All Types", ".*"), ("MP3", ".mp3")]))
self.playlist = self.filename.get()
playlist_pieces = self.playlist.split("/")
self.play_list.set (playlist_pieces[-1])
playl = self.play_list.get()
self.play_list_display.insert(END, playl)
print self.filename.get()
self.music = mp3play.load(self.filename.get())
pieces = self.filename.get().split("/")
self.trackLocations += [self.filename.get()]
self.name.set(pieces[-1])
def play(self):
"""Plays the .mp3 file"""
self.music.play()
def stop(self):
"""Stops the .mp3 file"""
self.music.stop()
def pause(self):
"""Pauses or unpauses the .mp3 file"""
if self.music.ispaused():
self.music.unpause()
else:
self.music.pause()
def vol(self, event):
"""Allows volume to be changed with the slider"""
v = Scale.get(self.volume_slider)
try:
self.music.volume(v)
except:
pass
def tune_changed(self, event):
idx = event.widget.curselection()[0]
self.music = mp3play.load(self.trackLocations[int(idx)])
print ("Now playing %s" % event.widget.get(idx))
def Exit(self):
exit()
if __name__ == "__main__":
musicplay()
ValueError: invalid literal for int() with base 10: 'The specified device is not open or is not recognized by MCI.'
I also struggled with this error after long google search i found on some German forum a post from some c++ guy who said it was because of ID3v2 tags with witch MCI has problems.
I then used mutagen - Python multimedia tagging library, to strip the tag from mp3 before playing it, since then i never encountered this error again. Also if resorting to mutagen make sure the mp3 file has write permission before stripping of its tag.

Categories

Resources