I'm trying to have the user select a file through a pop-up directory browser. Looking things up suggested that I use filedialog.askopenfile(), which works but leaves a small unresponsive tk window that I'd rather not have because any attempt to interact with it causes the kernel to crash and need to be restarted.
Does anyone have any solutions or alternatives? Thanks.
This works fine:
from tkinter import *
root = Tk()
root.withdraw()
filedialog.askopenfile()
Related
I've been trying to make use of the overrideredirect() function in tkinter, but I'm facing a small issue.
Here's a sample code snippet:
from tkinter import *
root = Tk()
root.geometry("500x500+200+200")
root.overrideredirect(True)
mainloop()
Here when I press Window + D the window minimizes like it's supposed to, but if I restore any minimized app or open a new application (like Chrome), the tkinter window gets restored too instead of staying minimized.
Is there any way to fix this problem? It would be great if anyone could help me out.
I'm curious, as making a window with Tkinter really does seem to easy. Does Python have an alert thing similar to javascript by default?
There is no graphical alert in python. Tkinter is the default python GUI interface. If all you need is an alert, that's less than a dozen lines of code. Here's a python 3 example:
import tkinter as tk
import tkinter.messagebox
def alert(message):
root = tk.Tk()
root.withdraw()
tkinter.messagebox.showwarning("Alert", message)
root.destroy()
alert("Danger Will Robinson!")
I can do the following in my program to get a simple open file dialog and print the selected file path. Unfortunately it doesn't go away right away when the user selects the file, and stays around for over 5 minutes. How do I make the window disappear immediately once a selection has been made before executing more python code? After the Tkinter code I do try to import some video using OpenCV which I think may be causing the slowing. My OpenCV code does execute properly and I don't think there is a problem with that alone (i.e. some interaction is causing the error & maybe some intensive process is started before Tkinter wraps up its GUI dialog).
import Tkinter as Tk
import cv2
from tkFileDialog import askopenfilename
root = Tk.Tk()
root.withdraw() # we don't want a full GUI, so keep the root window from appearing
filename = askopenfilename() # show an "Open" dialog box and return the path to the selected file
print(filename)
cap = cv2.VideoCapture('video.mp4') # this works just fine
I am using Python 2.7 and Mac OS X 10.9 if that is useful.
[EDIT: This does not seem to be a problem for all, but it is for me, so I am changing the question to also include debugging the problem. I don't want anything to execute until the Tkinter open file dialog window is done closing in the GUI. It seems that a subsequent step in my program (an open cv video import) could somehow be causing Tkinter to slow things down, so I want to ensure it does close before any new process is started. Again, the Tkinter window does actually close after 5 minutes...]
I was having some trouble with Tkinter dialog boxes. Like you, the dialog just sat there after I had selected a file. I didn't try leaving it for very long, it may have disappeared after 5 minutes as you said your's did. After lots of random experimentation I found that calling root.update() before the askopenfilename() line seemed to fix it.
For reference, this is the code I was testing with:
import sys
from tkinter import *
from tkinter import filedialog
#instantiate a Tk window
root = Tk()
#set the title of the window
root.title('Tk test')
# I don't know, what this does, but it fixes askopenfilename if I use it.
root.update()
print(filedialog.askopenfilename(title='dialogue? surely.'))
Exactly the problem I had - sometimes the file dialog would go away after a while, sometimes not. But it always seemed to block a later status windows. Adding the root.update() fixed both problems immediately.
My python application launches a subprocess that creates a pyglet window. When the pyglet window opens, it is in front of all other windows, and takes keyboard focus. I'd like my pyglet window to open in the background, and not take focus. Is this possible?
Stripped-down version of the code I'm using:
import pyglet
pyglet.window.Window()
pyglet.app.run()
I'm using Windows 7, in case that makes a difference..
Reversing focus is OS specific:
pyglet does not provide OS specific window control. So most likely you will have to use an ad-hoc trick for quick&dirty solutions or try to approach it with extensions like pywin32 using Windows API and/or COM to list through the stack of taskbar applications to reverse stealing of focus. You can also try to create your own window (container - which you can manipulate) first - in order to delegate its context to pyglet.
Delaying stealing of focus
On the other hand if according to your program logic you just want to delay actual showing of you application you can play with visibility:
import pyglet
w = pyglet.window.Window()
w.set_visible(False)
pyglet.app.run()
So if you don't want to play with delegation of window context, you can probably do the following:
start your application w/o showing the window
find the focus of the current active window by getting its handle/id
show your window
give back the focus to the previous window
The above assumes working with windows API. I think MSDN had examples on focus changing.. If you know PID of your current window (main application) this should simplify the step 2.
I am thinking this might be more of a windows / window manager issue than your app - will something like this http://pcsupport.about.com/od/windowsxp/ht/stealingfocus02.htm help ??
I'm working on a graphical app, and at the start of the run I'd like to ask the user a single configuration question. The graphical framework (Panda3D) has ugly default dialog boxes, so I'd like to use something like tkInter to provide a modal dialog. I tried this:
import Tkinter
import tkMessageBox
root = Tkinter.Tk()
# hide the root window
root.withdraw()
config.PLAY_MUSIC = tkMessageBox.askyesno( "My App",
"Would you like this app to play music from your iTunes collection?" )
root.destroy()
This does what I want it to, but it appears to route all further keyboard events to tkInter rather than my Panda3D app. I don't need to do anything further with tk after this dialog.
I can put the tk dialog into a separate app that chains onto mine, I suppose, but I'm wondering if there's a way to kill tk and get the keyboard back without exiting my app entirely.
Update: Tried root.quit(), which does seem to get the keyboard back, but I get a "Fatal Python error: PyEval_RestoreThread: NULL tstate" crash on exit from my program, which isn't ideal.
Have you tried:
grab_release(self)
Which does: Release grab for this widget if currently set.
Where "A grab directs all events to this and descendant
widgets in the application."
as in:
root.grab_release()
Hope you haven't tried this one.