Having trouble with Tkinter OptionMenu - python

I am using Tkinter in Python to get user input (Tkinter.Entry) for a folder-path. When the user clicks a button on the GUI, this path is then accepted (get.Entry) and a list of files in that path is created (os.listdir)
I want a drop-down menu OptionMenu to display this list.
My current code does not display the list of files even when the filelist variable is non-empty. Why would this be happening?
After the code has completely run, I checked filelist and found that it is not empty.
Why does the OptionMenu see it as empty then?
Following is my code:
import os
import tkinter as tk
from tkinter import ttk
from IPython.core.debugger import set_trace
filepath = ""
filename = ""
filelist = [""]
root = tk.Tk()
def click():
global filepath, filename, filelist
filepath = e.get()
filelist = os.listdir(filepath)
myLabel = tk.Label(root,text = filelist).pack()
path = tk.StringVar()
e = tk.Entry(root,textvariable = path)
e.pack()
myButton = tk.Button(root, text = "click", command = click).pack()
optionVar = tk.StringVar()
op = tk.OptionMenu(root,optionVar,*filelist)
op.pack()
root.mainloop()
Pic1 shows the contents of my folder.
enter image description here
I figured out that the curly brackets seen around some items in the filelist array are because of the spaces in the filenames.
Pic2 shows the output of the script. Print(filelist) by itself shows empty filelist.
When the 'click' button is pressed, the Label prints the filelist with three items.
But the OptionMenu does not see this updated filelist.
enter image description here

Related

I am trying to make a exe similar to windows file explorer with python using os.path and tkinter

from PIL import Image
from tkinter import filedialog as fd
import os
import ctypes
import tkinter
class ImageList:
path = ""
dir = ""
top = tkinter.Tk()
canvas = tkinter.Canvas()
canvas.pack()
def __init__(self):
self.path = os.path.expanduser('~/')
def findImage(self):
image = Image.open(self.dir, "rb")
image.show()
def fileExplorer(self, path):
self.canvas.destroy()
self.canvas = tkinter.Canvas()
self.canvas.pack()
obj = os.scandir(path)
for entry in obj:
if entry.is_dir():
#self.path = os.path.abspath(self.path)
b = tkinter.Button(self.canvas, text=entry.name, command=lambda: self.fileExplorer(os.path.abspath(entry).replace('//', '\\')))
b.pack()
elif entry.is_file():
b = tkinter.Button(self.canvas, text=entry.name, command=lambda: print(entry.name))
b.pack()
else:
obj.close()
self.top.mainloop()
As shown in the code above, I am trying to make exe that shows the subdirs and files after C:\Users using buttons in tkinter and repeating it by using recursion.
The first error is that in "os.path.abspath(entry).replace('//', '\')" shows path in a format of "C://Users" and I intended to change that to "C:\Users" using the replace method. However, using "\" doesn't replace "//" and still shows as the original format.
The second error is that after running the code, when I press any button it acts as if I pressed the last button in the tkinter window, meaning that it recursively called the last subdir or the file below "C:\Users".
I'm just getting used to python and this is my first time using stackoverflow. I'm sorry if I did not abide by any of the rules in stackoverflow. Thanks for anyone helping.

how to save the name of the app chosen in tkinter filedialog

from tkinter import *
from tkinter import filedialog
def openFile():
global pathFile
file_path = filedialog.askopenfilename()
path.set(file_path)
pathFile = path.get()
#file_name = ' for example google chrome'
root = Tk()
path = StringVar()
button = Button(text="Choose a program", command=openFile)
button.pack()
root.mainloop()
For example lets say the user chooses to pick chrome.exe, I want the name Google Chrome to be saved in the file_name variable. How can I do that.
Edit: I dont wan't to use the os.path.basename method,the name should be whatever is typed here
Screenshot 1
Screenshot 2

Update a label with the file's name, AFTER the file has been selected in the dile directory

Before a file is selected, the GUI will have a blank space where the file's name should be. After the file is selected, the GUI should update, and the name of the file selected should be displayed. I have made many different attempts at this, and the program does execute properly, however the name of the file is not displayed. I will show, as best I can, what the GUI should looke like before and after the file is selected
I have tried setting a StringVar() and having the label it is associated with update appropriately, however it has not worked so far. If I had to guess what was wrong, I would guess that the window ins't updating properly, but I am not sure.
import tkinter as tk
from tkinter import StringVar
from tkinter import ttk
from tkinter import filedialog
#Wraps two functions inside an object which allows both functions to use filename#
class PDFSelector:
#Allows user to select PDF to use in program#
def select_PDF(self):
#Opens file directory to select a file, and shows both folders and PDF files only#
#This should be what changes lbl1a below to the name of the file selected)
self.filename = filedialog.askopenfilename(initialdir = "/", title = "Select file", filetypes = (("pdf files", "*.pdf"), ("all files", "*.*")))
file_name.set(self.filename)
window.update_idletasks()
window.update()
#----Main----#
#Creates an instance of the wrapped functions to use the GUI#
selector = PDFSelector()
#Creats the GUI that will be used to select inputs#
window = tk.Tk()
window.geometry("600x130")
window.title("Word Frequency Program")
window.resizable(0, 0)
#Just a simple label on the GUI#
#The name of the file should appear next to "File Selected" AFTER the file has been selected by the user
lbl1 = tk.Label(window, text = "File Selected: ")
lbl1.grid(row = 1, column = 1)
file_name = StringVar()
lbl1a = tk.Label(window, textvariable = file_name)
lbl1a.grid(row = 1, column = 2)
#Calls the select_PDF method to choose a PDF for the program to read#
button1 = ttk.Button(window, text = "Select File", command = selector.select_PDF)
button1.grid(row = 1, column = 4)
window.mainloop()
window.destroy()
GUI should display the name of the file
Apparently the code does work, however there is something on my end that does not display the updated name of the PDF selected. This is for anyone who finds this question in the future, that the code I wrote works.

Python - tkinter and glob.glob working togheter

Im new to tkinter and trying to open the explorer (on windows) so that i can chose what folder i want to use in my program. I found a template for tkinter and altered it to work with my function and how i need the filepath to be. Before i tried using tkinter to "select my folder", i had manually writen the directory in the glob.glob function like this glob.glob(r'C:\Users\Desktop\Spyder\*.log') (and it worked). So my new ide was to replace the pathname input from r'C:\Users\Desktop\Spyder\*.log' to a variabel that stored the same pathname but now it used tkinters askdirectory() to finde the directory inteed.
import glob
import os
from itertools import zip_longest
import tkinter as tk
from tkinter import filedialog
#-------------Connect to Access2013------------------
class Application(tk.Frame):
def __init__(self, master=None):
super().__init__(master)
self.pack()
self.create_widgets()
def create_widgets(self):
self.select_folder = tk.Button(self)
self.select_folder["text"] = "Open WindowsExplorer"
self.select_folder["command"] = self.ask_directory_to_folder
self.select_folder.pack(side="top")
self.quit = tk.Button(self, text="QUIT", fg="red",
command=root.destroy)
self.quit.pack(side="bottom")
def ask_directory_to_folder(self):
clerdatabase() # a funktion that resets the autonumber and deleats all data from every table
print("Open!")
filepath = filedialog.askdirectory()
log_filepath = "r'"+ str(filepath +"/*.log'")
right_log_filepath = log_filepath.replace('/','\ ').replace(' ','')
find_filenames(right_log_filepath)
root = tk.Tk()
app = Application(master=root)
app.mainloop()
#--------------Scan selected folder for .log files and starts to scan files---------
def find_filenames(right_log_filepath): #finds every file in the chosen filepath
print(right_log_filepath) # r'C:\Users\Desktop\Spyder\*.log'
print("ok")
filenames = [] # list for all the found filenames
for filepath_search in glob.glob(str(right_log_filepath), recursive=True): #A for loop that opens every .log file in the chosen directory folder
print('run')
My problem ist that i don´t get the for loop filepath_search to work (it prints "ok"). But the word run inside the for loop dose not print, i guess it´s because it gets stuck somewhere before that? Someone who has more experience with tkinter that can help me? Thanks
I guess issue caused by what is passed to glob.glob since it doesn't find anything. It seems that it is mostly related to the fact that you add ' characters at the beggining and end of your right_log_filepath.
In ask_directory_to_folder function replace:
log_filepath = "r'"+ str(filepath +"/*.log'")
right_log_filepath = log_filepath.replace('/','\ ').replace(' ','')
find_filenames(right_log_filepath)
With:
from os import path # should be at the top of your file
log_filepath = path.join(filepath, "*.log")
find_filenames(log_filepath)

How to assign a button click into a variable on tkinter

I want to create a tkinter window, where it will appear the files of a folder as a dropdown menu and a Select button, such that when I select an element from the previous list the full path will be saved into a new variable. Apparently, I need to give an appropriate command.
from Tkinter import *
import tkFileDialog
import ttk
import os
indir= '/Users/username/results'
root = Tk()
b = ttk.Combobox(master=root, values=os.listdir(indir)) # This will create a dropdown menu with all the elements in the indir folder.
b.pack()
w = Button(master=root, text='Select', command= ?)
w.pack()
root.mainloop()
I think what you need here is actually a binding. Button not required.
Here is an example that will list everything in your selected directory and then when you click on it in the Combo Box it will print out its selection.
Update, added directory and file name combining to get new full path:
from Tkinter import *
import tkFileDialog
import ttk
import os
indir= '/Users/username/results'
new_full_path = ""
root = Tk()
# we use StringVar() to track the currently selected string in the combobox
current_selected_filepath = StringVar()
b = ttk.Combobox(master=root, values=current_selected_filepath)
function used to read the current StringVar of b
def update_file_path(event=None):
global b, new_full_path
# combining the directory path with the file name to get full path.
# keep in mind if you are going to be changing directories then
# you need to use one of FileDialogs methods to update your directory
new_full_path = "{}{}".format(indir, b.get())
print(new_full_path)
# here we set all the values of the combobox with names of the files in the dir of choice
b['values'] = os.listdir(indir)
# we now bind the Cobobox Select event to call our print function that reads to StringVar
b.bind("<<ComboboxSelected>>", update_file_path)
b.pack()
# we can also use a button to call the same function to print the StringVar
Button(root, text="Print selected", command=update_file_path).pack()
root.mainloop()
Try something like this:
w = Button(master=root, text='Select', command=do_something)
def do_something():
#do something
In the function do_something you create what you need to get the full path. You can also pass vars into the command.
get()
Returns the current value of the combobox.(https://docs.python.org/3.2/library/tkinter.ttk.html)
from Tkinter import *
import tkFileDialog
import ttk
import os
indir= '/Users/username/results'
#This function will be invoked with selected combobox value when click on the button
def func_(data_selected_from_combo):
full_path = "{}/{}".format(indir, data_selected_from_combo)
print full_path
# Use this full path to do further
root = Tk()
b = ttk.Combobox(master=root, values=os.listdir(indir)) # This will create a dropdown menu with all the elements in the indir folder.
b.pack()
w = Button(master=root, text='Select', command=lambda: func_(b.get()))
w.pack()
root.mainloop()

Categories

Resources