I am trying to activate a function in python which will save a timestamp to a file. However, I wish to activate that function after the first mouse click that accurses outside the Tk window.
For example, after running the program I will minimize it and press on the chrome browser icon and while doing so my program will log the time stamp.
I tried to use the bind function but it works for clicks that accrue only in the Tk window
By the way, I am currently using Tkinter as my GUI platform however if there is a way to do it with another libraries please share and I will adjust my program
thanks :)
Use the <FocusOut> event:
import tkinter as tk
root = tk.Tk()
def focus_lost(event):
print("Clicked outside the window")
root.bind("<FocusOut>", focus_lost)
root.mainloop()
If you are focussed on the tkinter window (e.g. if you have clicked on it), then when you click elsewhere it will detect this as a <FocusOut> event.
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 currently working with Tkinter and Python 2.7 on Linux and I was wondering if there was a way to remove the TK() window border frame and title bar without using overrideredirect(1).
I have my own close button and overrideredirect(1) presents me with a few issues that I can't accept:
GUI always on top
can't iconify then deiconify properly
no keyboard input so can't type into fields (see python tkinter overrideredirect; cannot receive keystrokes (Linux))
I can't use attributes("-fullscreen", True) as the titlebar and borders remain.
The window decoration is all handled by the window manager so what you are trying to do is find a way to tell the window manager to decorate your window differently from a standard application window. Tk provides overrideredirect to have the window manager completely ignore this window but we can also use Extended Window Manager Hints to declare the intended use of this toplevel window to the window manager. This is done for instance for tooltip and splashscreen windows to allow the manager to provide minimal decoration and possibly special animations.
In your case, adding a 'splash' hint should do what you want
root = tk.Tk()
root.wm_attributes('-type', 'splash')
You will need Tk 8.5 or above for this.
You must give your root window name before your command.
Like this:
from tkinter import *
root=Tk()
root.wm_attributes('-fullscreen','true')
root.mainloop()
I'm building a console app, and would like to capture keystrokes in real time. The following code works perfectly until another window gets focus. From that point on, I'm not able to get back to a state where I can capture keystrokes and other events again with only the console visible.
import tkinter as tk
app = tk.Tk()
def handleKeypress(event):
key = event.char
if(key == 'q'):
app.destroy()
else:
print(key)
app.bind_all('<Key>', handleKeypress)
app.withdraw()
app.mainloop()
I've tried using various methods (grab and focus) to redirect the focus to my app. The best I was able to do was to get the Tkinter window visible and in focus with deiconify(), but I was not able to hide it again to make it as though the console is the only window.
Adding the following results in the Tkinter window appearing and disappearing repeatedly:
def lostFocus(event):
app.deiconify()
app.focus_force()
app.withdraw()
app.bind_all('<FocusOut>', lostFocus)
How can I go back to the state the application was in right after launch? Or even better, how can I force it to get all events without having to make the Tkinter window visible and in focus?
You can't do what you want. Tkinter is designed -- as are most GUI toolkits -- to only process events when it has the focus. That's the whole point of focus: for the OS to know where to send events.
The fact that it works initially is probably a bug in tkinter. Though, perhaps it can be explained by the fact that the window initially has focus, and when you withdraw the window the OS doesn't move the focus
The only way to restore focus is to make the window visible.
Here's an excerpt for a main menu using Python Tkinter
master = Tk()
lbl = Label(master, text = "Main Menu:")
lbl.grid(row=0,column=1)
def list():
import list
listb = Button(master, text = "Patient List", command=list, width=10)
listb.grid(row=1, column=1)
There's a button "Patient List" that when pressed, opens a window specified from a different python file.
My problem is that the Main Menu window suffers a bug where the window will collapse. The new window comes out fine, but after closing it, I can't use my Main Menu.
Also, on my other buttons. The Main Menu doesn't collapse, but let's say I have a button Add Patient and after clicking it, the Add Patient window appears. It's functional. And then I close it, either using the quit button I programmed in it, or the close button. The Main Menu won't open the Add Patient window again.
So how can I smoothly navigate from one python program to another? Without the main menu collapsing. While being able to open a window over and over again.
My Patient List program has a lot of customized gui programming in it. I think it's because I use a grid in my Main Menu, and it's not a grid in my Patient List. But it shouldn't be affecting the Main Menu because they're supposed to be separate programs.
When doing such program with TKinter I generally use Screen classes.
To your example it would be for example:
"MainScreen", "AddPatienScreen", ...
All are subclass of the Frame tkinter class.
My Tk app only display one screen and furnish function to destroy and replace one screen by another one.
I have not access to any code now, but I invite yourself to try this approach if you understand it. It lead to well separated code and had good results.
I may provide you a very short example if required.
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.