How to deselect an entry in Tkinter - python

A friend of mine was making a basic program using tkinter when he realized that even when you deselect an entry, the cursor still remains in that entry until you select another one. My question is, is this a technical issue? Also, is there any way for me to fix this?

use widget.focus_set() to change focus when mouse button is pressed
from tkinter import *
def change_focus(event):
event.widget.focus_set()
root = Tk()
Entry(root).pack()
Entry(root).pack()
root.bind_all('<Button>', change_focus)
root.mainloop()

Related

How do I bind the ListBox of a ComboBox in Python Tkinter

I am looking to make a bind that allows me to place a certain value depending on the key pressed by the user.
Here is an example code in which I do it:
from tkinter import *
from tkinter import ttk
v=Tk()
combo = ttk.Combobox(values=['item1','item2','item3','item4'], state='readonly')
combo.current(0)
combo.pack()
def function(Event):
if(Event.char in '1234'):
combo.set(f'item{Event.char}')
combo.bind('<Key>', function)
v.mainloop()
They will tell me "If that works, what are you doing asking this?"
Well it turns out that if the Combobox is deployed, the bind stops working.
How could the problem be solved?
I know that this part of the question should not be asked, since it has nothing to do with the problem in question. But I would like to ask that if something is wrong in this question, or misspelled, or whatever, be informed. The page of "how to ask a good question" does not serve me, since from my point of view, I do everything as they say there.
I did my best to make what is written here as detailed and understandable as possible.
Hope your understanding, thank you.
Based on what Henry Yik proposed and studying what was returned by Event.widget, I found the solution to the problem.
from tkinter import *
from tkinter import ttk
v=Tk()
# I create two test combobox
for _ in range(2):
combo = ttk.Combobox(values=['item1','item2','item3','item4'], state='readonly')
combo.current(0)
combo.pack()
# I create a test entry to test if the function correctly recognizes when it should be executed
entrada = Entry()
entrada.pack()
def function(Event):
"""
If Event.widget is a str and ends with ".popdown.f.l" I consider it to be the Listbox,
I get the path of the Combobox it belongs to and convert it to a widget.
Afterwards, I set the value of Event.widget to that of the supposed combobox.
"""
if(isinstance(Event.widget, str) and Event.widget.endswith(".popdown.f.l")):
Event.widget = v._nametowidget(Event.widget[:-len(".popdown.f.l")])
# If Event.widget is not a Combobox, it stops the execution of the function.
if(not isinstance(Event.widget, ttk.Combobox)):
return
if(Event.char in '1234'):
Event.widget.set(f'item{Event.char}')
v.bind_all('<Key>', function)
v.mainloop()

Cancel user window sizing

After a user manually resizes a tkinter window, it no longer shrinks to fit.
What tkinter command would revert it back to the 'shrink to fit' behavior?
I had a hard time remembering how to this, as it has been so long.
In Tcl use:
wm geometry . {}
Can one of the python people edit the answer and translate this for tkinter, thanks.
#Atlas435 wrote this code for tkinter:
import tkinter as tk
root=tk.Tk()
def normal():
root.geometry('')
b = tk.Button(root,text='shrink', command=normal)
b.pack()
root.mainloop()

Tkinter tkMessageBox disables Tkinter key bindings

Here's a very simple example:
from Tkinter import *
import tkMessageBox
def quit(event):
exit()
root = Tk()
root.bind("<Escape>", quit)
#tkMessageBox.showinfo("title", "message")
root.mainloop()
If I run the code exactly as it is, the program will terminate when Esc is hit. Now, if I un-comment the tkMessageBox line, the binding is "lost" after closing the message box, i.e. pressing Esc won't do anything anymore. This is happening in Python 2.7. Can you please verify if this is happening also to you? And let me know about your Python version.
Here is a way to "by-pass" the problem. It's a different approach, but it might help:
from Tkinter import *
import tkMessageBox
def msg_test():
tkMessageBox.showinfo("title", "message")
def quit(event):
exit()
root = Tk()
root.bind("<Escape>", quit)
btn = Button(root, text="Check", command=msg_test); btn.pack()
root.mainloop()
Using tkMessageBox via a button click, doesn't affect key binding, i.e. pressing Esc continues to work.
If I understand the problem, you get the bad behavior if you call tkMessageBox.showInfo() before calling mainloop. If that is so, I think this is a known bug in tkinter on windows.
The solution is simple: don't do that. If you need a dialog to show at the very start of your program, use after to schedule it to appear after mainloop has started, or call update before displaying the dialog.
For example:
root = Tk()
root.after_idle(msg_test)
root.mainloop()
The original bug was reported quite some time ago, and the tk bug database has moved once or twice so I'm having a hard time finding a link to the original issue. Here's one issue from 2000/2001 that mentions it: https://core.tcl.tk/tk/tktview?name=220431ffff (see the comments at the very bottom of the bug report).
The report claims it was fixed, but maybe it has shown up again, or maybe your version of tkinter is old enough to still have the bug.

string variable not working with

I have my main window, which i refer to as mainroot, and when i press a button the secondary window root should appear
in root there is an entry and i want it to be assigned to "hohoho" whenever i press anykey, so i tied it to KeyRelease event.
All i mentioned above is working when there is no mainroot, As in this code:
import tkinter as Tk
# mainroot=Tk.Tk()
root=Tk.Tk()
root.geometry("200x200")
myvar=Tk.StringVar()
entry=Tk.Entry(root,)
entry.pack()
entry.configure(textvariable=myvar)
entry.bind('<KeyRelease>',lambda event:printing())
def printing():
myvar.set("hohohohohohoho")
print('myvar is',myvar.get())
print('value is',entry.get())
root.mainloop()
# mainroot.mainloop()
but if you commented the root.mainloop() and uncommented root.mainloop() and # mainroot.mainloop() the text shown in entrystops following myvar.
what i found is that myvar is not working properly as it should.
anyone have any idea what am doing wrong or is this bug in tkinter or what?????
I know that entry.trace() is more elegant but i didn't use it because i am not very familiar with it.
thank you
any hint will be appreciated

tkinter optionmenu swapping place

After googling and searching in SO, I come here.
I am making a program, but when I run it, the optionMenu widgets go to the end of the display, despite being set on the grid on the program. Here's a relevant example:
from tkinter import *
root=Tk()
root.title("Generador documentos")
app=Frame(root)
app.grid()
sexoPat=Label(app, text ="Gender")
sexoPat.grid(row=0,column=0)
var1 = StringVar()
sexoPatDrop= OptionMenu(root,var1,'Male','Female')
sexoPatDrop.grid(row=1,column=0)
sexoPatCheck=var1.get()
nombPat=Label(app, text ="name here")
nombPat.grid(row=2,column=0)
nombPatTXT=Entry(app)
nombPatTXT.grid(row=3,column=0)
In this sample code, I needed to write app instead of root in OptionMenu(root,...)
It was furas who gave me the answer.

Categories