This question already has answers here:
Adding placeholders to tkinter Entry widget in a procedural way
(4 answers)
Closed 1 year ago.
How can I program a code in python Tkinter for entry box default text?
I want to add a default text that disappears as soon I click on the entry box.
To do that you simply would insert the default text into the Entry and then bind the Entry to getting focus and delete all that is in the entry and unbind the widget so that it doesn't delete everything in it the next time user clicks it.
import tkinter as tk
def clear_default(event):
event.widget.delete(0, 'end')
event.widget.unbind('<FocusIn>')
root = tk.Tk()
entry = tk.Entry()
entry.pack(padx=10, pady=10)
entry.insert(0, 'Default Text')
entry.bind('<FocusIn>', clear_default)
root.mainloop()
Tho if it is meant to be a default not just simply a placeholder, then you could instead of deleting when the widget receives focus, select all that is in the widget, so that when user starts typing the selection is deleted. This will be also helpful if the user wants to edit their entry:
entry.bind('<FocusIn>', lambda e: e.widget.select_range(0, 'end'))
Related
This question already has answers here:
Entry box text clear when pressed Tkinter
(2 answers)
Closed 6 years ago.
For instance:
from Tkinter import *
root = Tk()
e1 = Entry(root)
e1.insert(END, "ex. new file") #would like to make this text disappear when clicked
e1.grid(row=0, column=0)
root.mainloop()
Where the text "ex. newfile" disappears when clicked upon, leaving a blank entry field.
Create a boolean flag that monitors if the entry has been accessed; set it to False,
Bind "<Button-1>" to a function that clears the entry if it has not been accessed yet, and changes the flag to True.
Added
def delete_text(event):
if default_text:
e1.delete(0, END)
default_text = False
default_text = True
e1.bind("<Button-1>", delete_text)
Thanks to DYZ and effbot
I'm making a program on the Raspberry Pi with a touchscreen display.
I'm using Python Tkinter that has two entry widgets and one on screen keypad. I want to use the same keypad for entering data on both entry widgets.
Can anyone tell me how can i check if an entry is selected? Similar like clicking on the Entry using the mouse and the cursor appears. How can I know that in Python Tkinter?
Thank you.
There is always a widget with the keyboard focus. You can query that with the focus_get method of the root window. It will return whatever widget has keyboard focus. That is the window that should receive input from your keypad.
You can use events and bindigs to catch FocusIn events for your entries.
entry1 = Entry(root)
entry2 = Entry(root)
def callback_entry1_focus(event):
print 'entry1 focus in'
def callback_entry2_focus(event):
print 'entry2 focus in'
entry1.bind("<FocusIn>", callback_entry1_focus)
entry2.bind("<FocusIn>", callback_entry2_focus)
This question already has answers here:
Getting a callback when a Tkinter Listbox selection is changed?
(3 answers)
Closed 9 years ago.
I have a listbox on a GUI in Tkinter. I would like to implement a routine where if a listbox item is selected a function is called (based on this selection) to modify the gui (add another adjacent listbox). Then if that selection changes, the gui reverts back to its default view. Can this be done? Seems you would need to associate a function to a listbox selection, not sure how to do this or if its possible... Does anyone have the secret?
Its possible to add "select" buttons to the bottom of my listbox, but I wanted to avoid this extra work for user and save space on the GUI.
Thanks to all in advance! Daniel
The listbox will fire the virtual event <<ListboxSelect>> whenever the selection changes. If you bind to it, your function will be called whenever the selection changes, even if it was changed via the keyboard.
Ok nevermind, the link below answers my question with the example below:
http://effbot.org/tkinterbook/tkinter-events-and-bindings.htm
from Tkinter import *
root = Tk()
def callback(event):
print "clicked at", event.x, event.y
frame = Frame(root, width=100, height=100)
frame.bind("<Button-1>", callback)
frame.pack()
root.mainloop()
(replace frame with listbox widget of course)
Works !
I'm trying to prepopulate a text field based on the most recent entry. As this is not a Listbox, I don't see how to do it, and I'm not seeing any examples on the web. Thanks.
Update. I've managed to find a partial way of doing this. Still wondering, is it possible to supply suggested text in Tkinter which fades when the text box is clicked?
from Tkinter import *
app = Tk()
app.title("GUI Example")
app.geometry('560x460+200+200')
x = Text(app)
x.insert(END, "Before")
x.pack()
def replace():
x.delete(1.0, END)
x.insert(END, "After")
abutton = Button(app, text="Click me", command=replace)
abutton.pack()
app.mainloop()
Well, I personally don't know of any options to do this (any answers giving one will easily trump this one).
However, you can closely mimic this behavior with a little coding. Namely, you can bind the textbox to a function that will insert/remove the default text for you.
Below is a simple script to demonstrate:
import Tkinter as tk
tk.Tk()
textbox = tk.Text(height=10, width=10)
textbox.insert(tk.END, "Default")
textbox.pack()
# This is for demonstration purposes
tk.Text(height=10, width=10).pack()
def default(event):
current = textbox.get("1.0", tk.END)
if current == "Default\n":
textbox.delete("1.0", tk.END)
elif current == "\n":
textbox.insert("1.0", "Default")
textbox.bind("<FocusIn>", default)
textbox.bind("<FocusOut>", default)
tk.mainloop()
Notice how:
When you click in the top textbox, the default text disappears.
When you click in the bottom textbox, the top one loses focus and the default text reappears.
This behavior will only occur if there is nothing in the top textbox.
I'm working on my first Python program and have little idea what I'm doing. I want to re-bind ctrl-a (control a) to select all text in a Text widget. The current binding is ctrl-/ (control /). The binding part jumps right to the function but the actual text selection doesn't work. Instead, the cursor jumps to the first character on the first line (like it should) and nothing else happens. I'm sure this is embaressingly easy to fix but after spending hour an hours on it, I can't figure out what's wrong.
Python 3, Windows:
from tkinter import *
# Select all the text in textbox (not working)
def select_all(event):
textbox.tag_add(SEL, "1.0", END)
textbox.mark_set(INSERT, "1.0")
textbox.see(INSERT)
# Open a window
mainwin = Tk()
# Create a text widget
textbox = Text(mainwin, width=40, height=10)
textbox.pack()
# Add some text
textbox.insert(INSERT, "Select some text then right click in this window")
# Add the binding
textbox.bind("<Control-Key-a>", select_all)
# Start the program
mainwin.mainloop()
So the new code is...
from tkinter import *
# Select all the text in textbox
def select_all(event):
textbox.tag_add(SEL, "1.0", END)
textbox.mark_set(INSERT, "1.0")
textbox.see(INSERT)
return 'break'
# Open a window
mainwin = Tk()
# Create a text widget
textbox = Text(mainwin, width=40, height=10)
textbox.pack()
# Add some text
textbox.insert(INSERT, "Select some text then right click in this window")
# Add the binding
textbox.bind("<Control-Key-a>", select_all)
textbox.bind("<Control-Key-A>", select_all) # just in case caps lock is on
# Start the program
mainwin.mainloop()
and yes it works flawlessly. Thank you, very much Bryan Oakley. Steven Rumbalski: that's a VERY good point, I've followed your advice as well.
You need to both do the selection and then inhibit the default action by having your function return the string "break".
This is due to how Tkinter processes events. It uses what it calls "bind tags". Even though it looks like you are binding to a widget, you are actually binding to a tag that is the name of the widget. There can also be bindings to the widget class, to the toplevel window that the widget is in, and the tag "all" (plus, you can invent your own tags if you wish).
The default ordering of these tags is from most-specific to least-specific, and events are processed in that order. Meaning, if you have a binding both on the widget (most specific) and the class (less specific), the binding will fire for the widget first, and then for the class binding (and then for the toplevel, and then for "all").
What this means is that by default, a binding on a widget augments rather than replaces a default binding. The good news is, you can inhibit any further bindings from firing by simply returning the string "break", which stops the chain of bindings from doing any more work.
You can do that with a module named pyautogui
Just run the command where you want to add the event,
import pyautogui
..., command=lambda *awargs:pyautogui.hotkey("ctrl","a")
Make sure you install the module. If you are on windows, install it by
pip install pyautogui