Reputation: 11
I'm new in Python and I'm trying to create a listbox that shows the name of the files in a subdirectory.
I've figure out how to display the name of the files, but only on the shell and I want them to be inside a listbox, so the user can choose a file and then click a button to display it's content on a canvas.
Any ideas? this is what I have so far:
import os
import fnmatch
from Tkinter import *
root=Tk()
root.title("Reader")
def open_book():
for file in os.listdir("/txtbooks"):
if fnmatch.fnmatch(file, '*.txt'):
print file
OpenBook=Button(root, text="Open Book",command=open_book)
booknames=(open_book)
listbox=Listbox(root,selectmode=BROWSE)
listbox.insert(END,booknames)
label= Label(root, text="Select a book")
label.pack()
listbox.pack()
OpenBook.pack()
can=Canvas(root,width=500,height=300)
scrollbar=Scrollbar(root)
scrollbar.pack(side=RIGHT,fill=Y)
can.pack()
mainloop()
Upvotes: 1
Views: 1794
Reputation: 385930
You have several problems in your code:
First, booknames = (open_book)
isn't creating a list of books. It's simply returning a reference to the function named "open_book". What you need to do is call the function, like so:
booknames = open_book()
Second, your open_book function needs to return values, not print them out. For example:
def open_book():
books = []
for file in os.listdir("/txtbooks"):
if fnmatch.fnmatch(file, '*.txt'):
books.append(file)
return books
(*alternately, you can use the yield statement to create a generator, but since you're just learning we'll keep this as simple as possible)
Third, to insert multiple items you must pass them to the function as distinct arguments. Python has a syntax for that: put a *
before a list to expand the list before the function is called:
listbox.insert(END,*booknames)
The above has the same effect as if you did this:
for book in booknames:
listbox.insert(END, book)
Finally, you have a logical issue. You are trying to call the open_book function both at startup and from a button. Maybe that's exactly what you intend, but the function needs to work differently in each context. In the case of calling it when you start up, you want it to return a list of books. To use it from a button click, you want it to insert the books in the list.
You can do this with two functions. The first collects the list of books and returns them, and the second inserts them in the list. So, something like this:
def insert_books():
books = open_book()
listbox.delete(0, "end")
listbox.insert("end", *books)
button = Button(..., command=insert_books)
Of course, once you have the insert_books function, you should use that in both places (assuming you want to do this in both places) so that you don't duplicate the "get-a-list-of-books-and-insert-them" logic.
listbox=Listbox(root,selectmode=BROWSE)
insert_books()
Upvotes: 2