Reputation: 25
I'm a complete newbie. I started last week with python in which I'm trying to create a functional GUI. This gui will make use of multiple tab's using ttk notebook. However, I'm experiencing a problem regarding to adding multiple listboxes in my programm. I do have a working listbox, in "tab11". But, whenever I try to add a simple listbox it won't render when I run the program. The shell however supplies me with an error, I don't have any clue what the problem is.
The error I get is:
Traceback (most recent call last):
File "/Users/nielsschreuders/Documents/01_TUe_B32_Feb13_Jun13/Project/Concept/prototype/python/RaspberryBackup/B32Project/PythonExperiments/multipleListboxTest.py", line 133, in <module>
listbox2 = tk.Listbox(tab12, width=50, height=-1)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/__init__.py", line 2608, in __init__
Widget.__init__(self, master, 'listbox', cnf, kw)
File "/Library/Frameworks/Python.framework/Versions/3.3/lib/python3.3/tkinter/__init__.py", line 2075, in __init__
(widgetName, self._w) + extra + self._options(cnf))
_tkinter.TclError: can't invoke "listbox" command: application has been destroyed
This is a simplefied version of the code:
import tkinter as tk
#import RPi.GPIO as gpio
import sys
import os
from tkinter import ttk
mGui = tk.Tk()
mGui.geometry('800x480')
mGui.title("Apps on Wheels")
nb = ttk.Notebook(mGui, name="notebook")
nb.pack(fill=tk.BOTH, expand=tk.Y, padx=2, pady=3)
dispColor="Yellow"
#create tabs
tab1 = ttk.Frame(nb, name="audioTab")
#assign tabs to notebook children
nb.add(tab1, text="Audio")
nbAS = ttk.Notebook(tab1, name="audioSource")
nbAS.pack(pady=100)
#nbAS.pack(fill=tk.BOTH, expand=tk.Y, padx=2, pady=3)
tab11 = ttk.Frame(nbAS, name="radioTab")
tab12 = ttk.Frame(nbAS, name="mp3Tab")
nbAS.add(tab11, text="Radio")
nbAS.add(tab12, text="MP3")
##################Radio Controller###################
def get_list(event):
#get selected line index
index = listbox1.curselection()[0]
#get the line's text
seltext=listbox1.get(index)
#delete previous text in enter1
enter1.delete(0, 50)
#display selected text
enter1.insert(0, "You are listening to: " +seltext)
intIndex = int(index)
intRadioFreq = intIndex +1
radioFreq = str(intRadioFreq)
os.system("mpc play " + radioFreq)
def set_list(event):
try:
index = listbox1.curselection()[0]
#delete old listbox line
listbox1.delete(index)
except IndexError:
index = tk.END
#insert edited item back into listbox1 at index
listbox1.insert(index, enter1.get())
def sort_list():
temp_list = list(listbox1.get(0, tk.END))
temp_list.sort(key=str.lower)
#delete contents of present listbox
listbox1.delete(0, tk.END)
for item in temp_list:
listbox1.insert(tk.END, item)
def save_list():
#get a list of listbox lines
temp_list = list(listbox1.get(0, tk.END))
#add a trailing newline char to each line
temp_list=[radio + '\n' for radio in temp_list]
#give the file new name
fout = open("radio_data2.txt", "w")
fout.writelines(temp_list)
fout.close()
#create the data file
str1 = """Radio 1
Radio 2
3FM Serious Radio
538 Radio
Radio 6 Soul & Jazz
"""
fout = open("radio_data.txt", "w")
fout.write(str1)
fout.close()
fin = open("radio_data.txt", "r")
radio_list= fin.readlines()
fin.close()
radio_list= [radio.rstrip() for radio in radio_list]
RadioFrequencies = tab11
#creat listbox
listbox1 = tk.Listbox(RadioFrequencies , width=50, height=-1)
listbox1.grid(row=0, column=0)
#use entry widget to display/edit selection
enter1 = tk.Entry(RadioFrequencies , width=44, bg=dispColor, fg="black", justify=tk.CENTER, font=("Arial" ,16, "bold"))
#enter1.insert(0, "Choose your radio station")
enter1.grid(row=1, column=0)
for item in radio_list:
listbox1.insert(tk.END, item)
listbox1.bind("<ButtonRelease-1>", get_list)
RadioFrequencies.mainloop()
listbox2 = tk.Listbox(tab12, width=50, height=-1)
listbox2.place(x=100, y=150)
listbox2.insert(tk.END, "entry here")
for item2 in ["one", "two", "three", "four"]:
listbox2.insert(tk.END, item2)
mGui.mainloop()
Upvotes: 1
Views: 1045
Reputation: 879591
Your program calls mainloop()
in two places:
RadioFrequencies.mainloop()
...
mGui.mainloop()
Generally speaking, a Tkinter app should call mainloop only once, and it is usually the tk.Tk()
instance that makes the call. Once the call is made, the program hands over the flow of control to the Tkinter event loop which manages all the GUI events.
Usually the call to mainloop()
would therefore be the last call in the script. When the GUI is exited, the script exits as well.
So remove the line
RadioFrequencies.mainloop()
The reason you are getting the error
_tkinter.TclError: can't invoke "listbox" command: application has been destroyed
is because after you close the GUI, Python returns from
RadioFrequencies.mainloop()
and then tries to call
listbox2 = tk.Listbox(tab12, width=50, height=-1)
but by this point the application has already ended.
Upvotes: 1