Matplotlib figures not working after Tkinter file dialog - python

I'm using the following function which I found as a reply to this question to show a dialog window for file selection.
[ Edit: Turns out the distro differences here are merely because Matplotlib is using gtk3agg on Fedora and TkAgg for drawing windows on each system ]
On Fedora 18: Everything works fine.
On Ubuntu 12.10: Matplotlib hangs after closing any figure displayed after the file dialog. For example, in the code below, on Ubuntu I can never get to the "made it" line. I am still able to type in the terminal, though nothing happens. If I remove the file dialog, Matplotlib figures work as expected.
import Tkinter, tkFileDialog
import pylab
def ask_for_config_file():
print "Please provide location of configuration file."
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
return file_path
def main():
config_file_path = ask_for_config_file()
pylab.figure()
pylab.show()
print "Made it."
Any suggestions?

I just needed a root.destroy() at the end of the dialog function!

Related

Tkinter not working the first time it runs with withdraw()

I am trying to make a Tkinter script to select files through Windows File Explorer. I don't need the Tkinter window to show, just the File Explorer interface.
import tkinter
from tkinter import filedialog
import os
window = tkinter.Tk()
#window.geometry("1x1")
window.withdraw()
def open_files():
files = filedialog.askopenfiles(mode='r')
global filenames
filenames = [os.path.abspath(file.name) for file in files]
window.destroy() # analysis:ignore #says "window" is undefined becasue of "del window" below
window.after(0, open_files)
window.mainloop()
del window
The first time I run this in Spyder, if window.withdraw() is not commented out, the console just shows runfile(*my_file_name*) and the code does... something... in the background, but nothing seems to actually happen. Nothing changes on-screen, but I cannot type in the console so I know the code is running.
If I open a new console tab and run the code with window.withdraw() commented out, everything works, and the Tkinter GUI is visible. If I then run this code again in the same tab, with window.withdraw() not commented out, then the code works as intended, with only the File Explorer window opening up, and the Tkinter GUI staying hidden. This is the case even if I click the "Remove all variables" button in Spyder, so as far as I understand the code is not saving any variables that allow it to run properly after the first time.
My question is, why does this code work the 2nd, 3rd, 4th, etc. time I run it, but not the first time?
I kept playing around, and changed -alpha to alpha and got this error:
TclError: wrong # args: should be "wm attributes window ?-alpha ?double?? ?-transparentcolor ?color?? ?-disabled ?bool?? ?-fullscreen ?bool?? ?-toolwindow ?bool?? ?-topmost ?bool??"
So I ended up changing window.attributes('-alpha',0) to window.attributes('-topmost',True, '-alpha',0), and this works! It brings up File Explorer on the first run without showing the Tkinter window. Thank you #Thingamabobs for your help.
My final code is:
import tkinter
from tkinter import filedialog
import os
window = tkinter.Tk()
window.attributes('-topmost',True, '-alpha',0)
filenames = [os.path.abspath(file.name) for file in filedialog.askopenfiles(mode='r')]
window.destroy()
del window

Tkinter askopenfilename() won't open

I have a selection of excel data that I am analyzing, and have just recently added the ability for the user to open the file explorer and locate the file visually, as opposed to entering the file location on the command line. I found this question (and answer) to make the window appear, which worked for a while.
I am still using the command line for everything except locating the file. Currently, this is a skeleton of what I have to open the window (nearly identical to the answer of the question linked above)
Tk().withdraw()
data_file_path = askopenfilename()
# other code with prompts, mostly print statements
Tk().withdraw()
drug_library_path = askopenfilename()
Once the code reaches the first two lines of code, the command line just sits with a blinking cursor, like it's waiting for input (my guess, for askopenfilename() to return a file location), but nothing happens. I can't ctrl+C to get out of the program, either.
I have found this question, which is close to what I'm looking for, but I'm on Windows, not Mac, and I can't even get the window to open -- most questions I see talk about not being able to close the window.
Thanks for any help!
Note: At this point in the program, no data from excel has been loaded. This is one of the first lines that is ran.
Try easygui instead. It's also built on tkinter, but unlike filedialog it's made to run without a full GUI.
Since you are using Windows, use this command in the command line (not in python) to install easygui:
py -m pip install easygui
then try this code:
import easygui
data_file_path = easygui.fileopenbox()
# other code with prompts, mostly print statements
drug_library_path = easygui.fileopenbox()
If you want to use an internal module, you can import tkFileDialog, and call:
filename = tkFileDialog.askopenfilename(title="Open Filename",filetypes=(("TXT Files","*.txt"),("All Files","*.*")))
I use this in many projects, you can add arguments such as initialdir, and you can specify allowable filetypes!
I had the same problem, but I found that the issue was that I was getting input with input() before I called askopenfilename() or fileopenbox().
from tkinter import Tk
from tkinter.filedialog import askopenfilename
var = input()
Tk().withdraw()
filepath = askopenfilename()
I simply switched the positions of askopenfilename() (or fileopenbox()) and input(), and it worked as usual.
Tk().withdraw()
filepath = askopenfilename()
var = input()

Repeated dialog window with Tkinter and Matplotlib on Mac OS X

I'm newbie in Tkinter. I try to use next code to open a file using tkFileDialog.askopenfilename and then plot something with Matplotlib:
import matplotlib.pyplot as plt
import Tkinter, tkFileDialog
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
x = range(10)
plt.plot(x)
plt.show()
After running the above script I get dialog window to open my file. After file selection I get repeated dialog window to open the file and a new window at the bottom of my screen. I know that the problem is because of plt.show(). What happens and how to avoid dialog window reopening? Should I set a Matplotlib backend for my task?
My versions:
Tcl/Tk 8.5.9
Matplotlib 1.3.1
Tkinter $Revision: 81008 $
OS X 10.9.4
I have found two related stackoverflow questions:
pyplot-show-reopens-old-tkinter-dialog and
matplotlib-figures-not-working-after-tkinter-file-dialog
but no answers. It seems that root.destroy() is not working for me.
When run with python test.py, the following seems to work for me:
import matplotlib.pyplot as plt
import Tkinter, tkFileDialog
root = Tkinter.Tk()
root.withdraw()
file_path = tkFileDialog.askopenfilename()
root.destroy()
print file_path
x = range(10)
plt.plot(x)
plt.show()
I think it works because the Tk instance for the file dialog is destroyed before matplotlib fires up its own. Interestingly, it also works for me when run from
ipython --pylab=tk
where I would have expected a problem with starting the event loop twice. The canonical solution in this case would be to check if Tk is already running before firing it up (again).
I'm on MacOSX 10.7.5, custom built matplotlib (shouldn't matter).
The only thing I noticed was that after experimenting with this, the touchpad swipe gestures on my Mac no longer work... Looking into this.
Edit
Here is a breakdown of the Tk commands executed by tkFileDialog.askopenfilename():
# breakdown of tkFileDialog.askopenfilename()
import Tkinter as Tk
window = Tk.Tk()
window.withdraw()
w = Tk.Frame(window)
s = w.tk.call('tk_getOpenFile', *w._options({}))
print s
w.destroy()
window.destroy()
When I run this (with python test.py), I get the file open dialog, where I can choose a file. Upon "OK" it prints the file name and exits. This works every time on my system. However, sometimes the 3-finger gestures on my touchpad stop working while running this program! And they don't come back after the program exits!! Not even after I kill the terminal the program was running in!!!
The only way I found to bring them back is to add the following matplotlib code to test.py:
import matplotlib
matplotlib.use('tkagg')
import matplotlib.pyplot as plt
plt.figure() # simplified from plt.plot(range(10))
plt.show()
and then click on the title bar of "Figure 1". This instantly brings back the 3-finger gestures. I suspect this is simply a bug in Tkinter. (I'm on Tcl/Tk 8.5, by the way)
I cannot reproduce the behavior that the file open dialog is constantly relaunched on my system.
Could you please describe what happens on your system if you launch test.py, without any matplotlib commands?
Alternatively, since Tkinter is old and apparently buggy, may I suggest to use Qt instead? Not only does it look much nicer, it is also snappier and I didn't have any problems with bugs.
Edit 2
I have broken down the Tk actions that matplotlib takes when executing the above commands in a non-interactive environment (i.e. with python test.py and not from iPython). These are the essential backend calls:
import matplotlib.backends.backend_tkagg as backend
figManager = backend.new_figure_manager(1)
figManager.show()
backend.show.mainloop()
These are still backend independent. I.e., for a Qt figure, simply use:
import matplotlib.backends.backend_qt4agg as backend
If we break this down further to the backend-specific layer, we have:
import matplotlib.backends.backend_tkagg as backend
import Tkinter as Tk
window = Tk.Tk()
window.withdraw()
# uncomment this to use the same Tk instance for tkFileDialog and matplotlib
#import tkFileDialog
#fname = tkFileDialog.askopenfilename(master=window)
#print fname
# figManager = backend.new_figure_manager(1)
from matplotlib.figure import Figure
figure = Figure()
canvas = backend.FigureCanvasTkAgg(figure, master=window)
figManager = backend.FigureManagerTkAgg(canvas, 1, window)
# figManager.show()
window.deiconify()
# backend.show.mainloop()
Tk.mainloop()
First, run with the tkFileDialog calls commented out and check if the matplotlib figure appears and behaves correctly. Then uncomment the tkFileDialog calls and see if you finally get the expected behavior.
If not, one has to continue breaking down FigureCanvasTkAgg and FigureManagerTkAgg to understand what is going on...
Edit 3
OK, since the problem persisted, let's break down matplotlib's Tk calls even further. The following code completely isolates all of matplotlib's Tk actions that I consider essential (so it is no longer necessary to import anything from matplotlib!). Note that I left out generating the toolbar and assigning lots of callbacks and keypress events. If the code below works now, then the problem lies with these. If it doesn't work, we can conclude that it is purely a Tk problem, and most likely a bug that should be reported. Here is the code:
import Tkinter as Tk
window = Tk.Tk()
window.withdraw()
# uncomment this to use the same Tk instance for tkFileDialog and matplotlib
#w = Tk.Frame(window)
#fname = w.tk.call('tk_getOpenFile', *w._options({}))
#print fname
#w.destroy()
# canvas = backend.FigureCanvasTkAgg(figure, master=window)
_tkcanvas = Tk.Canvas(master=window, width=640, height=480, borderwidth=4)
_tkphoto = Tk.PhotoImage(master=_tkcanvas, width=640, height=480)
_tkcanvas.create_image(320, 240, image=_tkphoto)
_tkcanvas.focus_set()
# figManager = backend.FigureManagerTkAgg(canvas, 1, window)
window.wm_title("Figure 1")
window.minsize(480, 360)
_tkcanvas.pack(side=Tk.TOP, fill=Tk.BOTH, expand=1)
# figManager.show()
window.deiconify()
# backend.show.mainloop()
Tk.mainloop()
Please play around with commenting out some lines and see if you can get it working correctly. If not, I would conclude that this is a bug in Tkinter, which should be reported.

askopenfilename window won't close

To allow my users to choose a file I'm using tkinter's askopenfilename. The function works fine, but after opening a file or pressing cancel the file open window goes empty and just stays open. The rest of the program moves forward correctly but even once the program ends the window remains open. And I'm not getting any errors. Is there anyone else who has experienced this behavior and has a solution? Alternatively, do you know any other easy methods of implementing a GUI file open prompt?
here's a pertinent example:
from Tkinter import Tk
from tkFileDialog import askopenfilename
Tk().withdraw()
filename = askopenfilename()
print(filename)

Python Tkinter not working in a .py file

My problem is that my python code is not working when I run it as a .py file. Here is the code:
import tkinter
tk=tkinter.Tk()
canvas=tkinter.Canvas(tk, width=500, height=500)
canvas.pack()
There is more code to it than that, but that is the relevant stuff. It works fine when I use the python shell or type it directly into the python console, but when I run it as a .py file, it seems to skip this code and go on to the rest, without displaying a canvas. I am using windows, but I am not sure what version of python I'm using.
I was also using
from * import tkinter
before, with relevant changes to the code and i changed it to try and help fix it. It didn't work :(
You are missing the eventloop at the end:
import tkinter
tk=tkinter.Tk()
canvas=tkinter.Canvas(tk, width=500, height=500)
canvas.pack()
# Enter into eventloop <- this will keep
# running your application, until you exit
tk.mainloop()
Only a personal recommendation: don't use tk as a variable name, use app or root or even win/window

Categories

Resources