tkinter askdirectory doesn't work from imported module - python

I have been using tkinter to supply a file dialog (in python 3.6) which allows users to select a directory. It works fine when it is a sub-function within the same module, but if I move that subfunction into a separate module and then try to import it from that module, it no longer works. Instead the code just hangs when the file dialog should pop up but it never appears.
working code:
This works if I run the main function
from tkinter import Tk
from tkinter.filedialog import askdirectory
def SelectDirectory():
# start up the tk stuff to have a file directory popup
print('start')
root = Tk()
print('postroot')
root.withdraw()
print('postwithdraw')
# let the user pick a folder
basepath = askdirectory(title='Please select a folder')
print('postselection')
root.destroy()
print('postdestroy')
return basepath
def main():
ans = SelectDirectory()
print(ans)
If I instead put this in another module and import it from that module, then it will print until 'postwithdraw' and then just hang.
submod.py:
from tkinter import Tk
from tkinter.filedialog import askdirectory
def SelectDirectory():
# start up the tk stuff to have a file directory popup
print('start')
root = Tk()
print('postroot')
root.withdraw()
print('postwithdraw')
# let the user pick a folder
basepath = askdirectory(title='Please select a folder')
print('postselection')
root.destroy()
print('postdestroy')
return basepath
and then run this:
from submod import SelectDirectory
def main():
ans = SelectDirectory()
print(ans)
It never gets past 'postwithdraw' and the file dialog never pops up.
Does anyone know what I am doing wrong here? I would think it has something to do with the tkinter window not appearing since its not the main module but is there some way to get past that?

Your both versions don't work. Both give 'module' object is not callable.
You have to use
root = Tk.Tk()
instead of
root = Tk()
and then both versions works.
Maybe two Tk in Tk.Tk() seems weird but usually we use lowercase tk instead of Tk in
import tkinter as tk
and then you have
root = tk.Tk()

Related

Trying to get a variable from a function using tkinter

I've been trying to get the printed output into a variable. Whenever I call the function it just simply repeats the button process. I tried to utilize global, but it doesn't seem to work.
Help pls thanks.
from tkinter import *
from tkinter import filedialog
import tkinter as tk
def openFile():
filepath = filedialog.askopenfilename(title="Open for me")
print(filepath)
window.destroy()
window = tk.Tk()
window.title("Insert Excel File")
window.geometry("200x200")
button = Button(text="Open",command=openFile,height=3,width=10)
button.pack()
window.mainloop()
print , outputs the string to stdout it does not store the value in a variable, you'll need to store it yourself.
Since you're using a callback you can't return the value. The best way to implement this is to use classes, the bad way is to use a global variable to store the result
I'm assuming you are not familiar with classes, so a possible solution would be
from tkinter import *
from tkinter import filedialog
import tkinter as tk
path = ""
def openFile():
global path
path = filedialog.askopenfilename(title="Open for me")
window.destroy()
window = tk.Tk()
window.title("Insert Excel File")
window.geometry("200x200")
button = Button(text="Open",command=openFile,height=3,width=10)
button.pack()
window.mainloop()
# do something with path e.g. print
print(path)

how to run multiple lines with variables in tkinter

Using Tkinter, os, and, pygame modules im finding all files and making a button to play the file because it will be an mp3 file but every time the function overwrites itself so I want to be able to write a function but inside the command parameter in the Tkinter button so it isn't a function but it operates like one
the code i already have:
import os
import pygame
import tkinter as tk
dir_path = os.path.dirname(os.path.realpath(__file__))
d = dir_path+"\\mp3s"
root = tk.Tk()
frame=tk.Frame(root)
root.title("title")
frame.pack()
for path in os.listdir(d):
full_path = os.path.join(d, path)
full_name = os.path.basename(full_path)
def playsong():
pygame.init()
pygame.mixer.music.load(full_path)
pygame.mixer.music.play()
play = tk.Button(frame,
text=full_name,
command=playsong)
play.pack()
root.mainloop()
the function inside the for statement is getting overwritten and I knew this would happen but I was still going to try this works for one file but I want a bunch of different files inside of the folder named "mp3s"
the rest of the code works this is the part that does not
def playsong():
pygame.init()
pygame.mixer.music.load(full_path)
pygame.mixer.music.play(
I wanted to run multiple functions in a line more specifically than lines and I figured out how to do this using lambda
import tkinter as tk
root = tk.Tk()
frame=tk.frame(root)
button = tk.Button(frame, text="name", command= lambda: [func1(), func2()])

Python TkInter create a button to open a specific directory

I want to create a button that opens the special directory like "C:\Users\", But as I searched, I did not find any code except the following code:
from tkinter import *
from tkinter import ttk
from tkinter import filedialog
gui = Tk()
gui.geometry("100x100")
def getFolderPath():
filedialog.askdirectory()
btnFind = ttk.Button(gui, text="Open Folder",command=getFolderPath)
btnFind.grid(row=0,column=2)
gui.mainloop()
What is the correct way to solve this problem?
Use os.startfile("C:\\Users") to use the system file explorer to open the directory.

Why always have to force quit python launcher after running Tkinter on Mac?

I'm using jupyter notebook on mac, recently I need to write interactive dialog box, so after google, I use Tkinter to make an interactive window.
But I was bothered by this problem couples day ,and still can't find a solution way.
Fisrt example:
from Tkinter import *
from tkFileDialog import askopenfilename
import sys
import os,time
def callback():
name= askopenfilename()
print name
errmsg = 'Error!'
Button(text='File Open', command=callback).pack(fill=X)
mainloop()
Second example:
from Tkinter import *
import sys,os
class YourApp(Tk):
def quit_and_close(self):
app.quit()
#os._exit(0)
#sys.exit(1)
#exit(0)
app = YourApp()
app.title('example')
app.geometry('400x300+200+200')
b = Button(app, text = "quit", command = app.quit_and_close)
b.pack()
app.mainloop()
And the third one:
import Tkinter as tk
import tkMessageBox
def ask_quit():
if tkMessageBox.askokcancel("Quit", "You want to quit now? *sniff*"):
root.destroy()
root = tk.Tk()
root.protocol("WM_DELETE_WINDOW", ask_quit)
root.mainloop()
After running those above code, always need have to force quit python launcher.
It is very weird, and annoying because after forcing quit, I will got the error:
Is it necessary to use python launcher as default window?
Is there possible to set another window to open ?
or is there proper way to close the launcher without causing programming crash?
p.s Even I try to use wxpython, it still open python launcher and got the same problem.

Tkinter not working in cmd (working in IDLE)

I am trying to display a directory selection dialog box (for getting a path and then for saving downloaded stuff).The code runs fine in IDLE but when i try to run it in CMD i get this error
NameError: name 'Tk' is not defined
I am using tkinter for gui.
Code Snippet
from tkinter import filedialog
root = Tk()
root.withdraw()
filename = filedialog.askdirectory()
Using Python 3.4.3. Any help/suggestions?
The statement from tkinter import filedialog only imports the filedialog module from tkinter. If you want the usual Tkinter stuff, you have to import that too. I'd recommend import tkinter as tk and then referring to it with e.g. root = tk.Tk() so you don't just dump everything into the global namespace. Or, if you really just want the root object, use from tkinter import Tk.
from tkinter import Tk
from tkinter import filedialog
root = Tk()
root.withdraw()
filename = filedialog.askdirectory()

Categories

Resources