tkinter filedialog opens 2 windows [duplicate] - python

When I run this script, two windows appear, one for the file selection and the Tkinter window. How can I change this so that the Tkinter window only opens after a file has been selected? Thanks
def main():
my_file = askopenfilename()
stage1()
def stage1():
master = Tk()
master.mainloop()

The window master does open only after the file dialog closure (try to change its title to check), the first window you see is the parent window of the file dialog. Indeed, the tkinter file dialogs are toplevel windows, so they cannot exist without a parent window. So the first window you see is the parent window of the file dialog.
The parent window can however be hidden using the withdraw method and then restored with deiconify:
from tkinter import Tk
from tkinter.filedialog import askopenfilename
def main():
master = Tk()
master.withdraw() # hide window
my_file = askopenfilename(parent=master)
master.deiconify() # show window
master.mainloop()
if __name__ == '__main__':
main()

Related

force Toplevel Widget on top of root widget

I have a tkinter app with a Toplevel widget that I want to create when the window is starting. The issue I have is that the Toplevel window always ends up behind the main window. Is there a way to force it in front of the root window?
To expand on #acw1668's comment, here's an example of how to create a transient window that sits on top of the root window. Note that a transient window will only have a close button [X], and no minimize / maximize buttons.
import tkinter as tk
from tkinter import ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.new_window_button = ttk.Button(
self,
text='Open New Window',
command=self.new_window,
)
self.new_window_button.pack()
def new_window(self):
self.dialog_window = tk.Toplevel(self)
self.dialog_window.transient(self) # place this window on top of the root window
if __name__ == '__main__':
app = App()
app.mainloop()
One important thing to consider is that you might want to prevent the user from interacting with the root window while the dialog is open. Otherwise, in the case of this example, the user could keep clicking the button and spawning new windows. You can do this by calling grab_set() on the dialog (thanks #acw1668 for reminding me)
def new_window(self):
self.dialog_window = tk.Toplevel(self)
self.dialog_window.transient(self) # place this window on top of the root window
self.dialog_window.grab_set() # hold focus

Command execution on closing "X" Tkinter MessageBox

I am trying to restart my main GUI/Halt the program flow when I Click on the "X" button in my tkinter messagebox . Any idea how can I do this ?
PS: I have read the many threads about closing the main GUI itself but nothing specific to messagebox
By default , my code proceeds to ask me for an output path using the filedailog.askdirectory() method when clicking "ok", or on closing the messagebox
My message box and the main GUI in the background
There's no simple way to add a custom handler to the "X" button. I think it's better to use messagebox.askokcancel() variation of messageboxes instead of showinfo, and halt the program if the returned result is False:
import tkinter as tk
from tkinter import messagebox, filedialog
root = tk.Tk()
def show_messagebox():
result = messagebox.askokcancel("Output path", "Please select an output file path")
if result:
filedialog.askdirectory()
else:
messagebox.showinfo("Program is halted")
tk.Button(root, text="Show messagebox", command=show_messagebox).pack()
root.mainloop()
Or, even simpler, you can just show filedialog.askdirectory() directly. If the user doesn't want to choose directory, they can click on the "Cancel" button, and then the program checks if there was empty value returned, and halts if so:
import tkinter as tk
from tkinter import messagebox, filedialog
root = tk.Tk()
def show_askdirectory():
directory = filedialog.askdirectory(title="Please select an output file path")
if not directory:
messagebox.showinfo(message="The program is halted")
else:
messagebox.showinfo(message="Chosen directory: " + directory)
tk.Button(root, text="Choose directory", command=show_askdirectory).pack()
root.mainloop()

how do I get Tkinter askopenfilename() to open on top of other windows?

I am running a script that prompts the user for a file. There is no gui except for the file browser that opens up. I have 2 options: browse for file, or select entire folder using askdirectory(). The latter opens on top of all other windows, but the first one opens under everything, I have to minimize other windows to find it.
Here is the method I'm using for these operations
from Tkinter import Tk
from tkFileDialog import askdirectory, askopenfilename
root = Tk()
root.withdraw()
self.inpath = askdirectory() # To open entire folder
Path = askopenfilename() # Open single file
root.destroy() # This is the very last line in my main script.
This is everything Tk related in my code. askdirectory opens on top, askopenfilename doesn't.
Is there a way to force it to open on top?
root.wm_attributes('-topmost', 1) did it for me. I found it in another SO thread to be honest :-).
I had the same problem.
For me it works with:
file = filedialog.askopenfilename(parent=root)
So, the file dialog gets in front of toplevel window without uncomment root.attributes("-topmost", True)
I want to share that the following lines worked superbly in my case. But I had to use both window.wm_attributes('-topmost', 1) and window=parent to make this work, see below:
import tkinter as tk
from tkinter import filedialog
window = tk.Tk()
window.wm_attributes('-topmost', 1)
window.withdraw() # this supress the tk window
filename = filedialog.askopenfilename(parent=window,
initialdir="",
title="Select A File",
filetypes = (("Text files", "*.txt"), ("All files", "*")))
# Here, window.wm_attributes('-topmost', 1) and "parent=window" argument help open the dialog box on top of other windows
I had the same issue of the file dialog window opening below my current window but I couldn't reproduce the issue with your code (in Python 2 or 3).
This is the minimal example where the issue occurs (context is Windows 10, Python 3, script is called from Idle, and note the input function:
File dialog opens below:
from tkinter import filedialog, Tk
root = Tk()
root.withdraw()
input("\nType anything> ")
file = filedialog.askopenfilename()
To open file dialog on top, both root.lift() or root.attributes("-topmost", True) work (but the latter is specific for Windows)
from tkinter import filedialog, Tk
root = Tk()
#root.attributes("-topmost", True) # this also works
root.lift()
root.withdraw()
input("\nType anything> ")
file = filedialog.askopenfilename()
I'm running python 3.x so there is a difference in code, but both opened on top for me. Try giving it focus, it should put in on top.
self.inpath.focus()
I'm not sure if it's gonna work, since I cant reproduce the problem.

Python Tkinter Toplevel not the active window

I have a Python Program that opens a Toplevel window which is working I just wanted to know if there is an option to set the Toplevel window window to be active once it has been opened because at the moment it is still showing the parent window as the active window after opening it.
The python code (Python 3.4.1)
from tkinter import *
class cl_gui:
def __init__(self, master):
master.title("DataBox")
menu = Menu(master)
master.config(menu=menu)
menu_users = Menu(menu, tearoff=0)
menu.add_cascade(label="Users", menu=menu_users)
menu_users.add_command(label="View", command=self.f_openUsers)
def f_openUsers(self):
top = Toplevel()
top.title("Users")
root = Tk()
app = cl_gui(root)
root.mainloop()
You can set focus onto the new Toplevel widget as follows:
def f_openUsers(self):
top = Toplevel()
top.title("Users")
top.focus_set() # <- add this line
See e.g. this handy tkinter guide.

Tkinter window not closing after closed file dialog

I would like to close the File Open dialog after selecting a file. Currently with my code, I can select a file but the File Open dialog remains open until I click the 'X'. How can I close this window after I have selected a file.
Here is my code:
import sys
from tkinter import *
from tkinter.filedialog import askopenfilename
fname = "unassigned"
def openFile():
global fname
fname = askopenfilename()
if __name__ == '__main__':
b = Button(text='File Open', command = openFile).pack(fill=X)
mainloop()
print (fname)
The file dialog is closing just fine. I think what you are trying to say is that the Tkinter window you created to hold the button is not closing after you select a file from the dialog. To have it do this, you will need to restructure your program a bit.
First, you need to explicitly create a Tk window to hold the button:
root = Tk()
You should then list this window as the button's parent:
Button(root, text='File Open', command = openFile).pack(fill=X)
# ^^^^
Finally, you should call the destroy method of the root window at the end of openFile:
root.destroy()
This will cause the window to close and the Tkinter mainloop to exit.
In all, your script will look like this:
import sys
from tkinter import *
from tkinter.filedialog import askopenfilename
fname = "unassigned"
def openFile():
global fname
fname = askopenfilename()
root.destroy()
if __name__ == '__main__':
root = Tk()
Button(root, text='File Open', command = openFile).pack(fill=X)
mainloop()
print (fname)

Categories