How do I prepopulate a text field with suggested text in Tkinter? - python

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.

Related

tkinter tag_config does not work

I am building a notepad like application in tkinter-python. There is an option to change the font of the text writen in the text field of the application.
I have created a Font Chooser popup screen to be called from main window on clicking 'font' menu, which basically creates a FontChooser class object and passes to the main window, which sets the font in man window.
A sample of the code where font is getting set in main window is,
root = Tix.Tk(className="Notepad")
notepad = ScrolledText(root, width=100, height=100)
def open_font():
font = MyFont.askChooseFont(root)
notepad.tag_add("bt", "sel.first", "sel.last")
notepad.tag_config("bt", font=font.getFontTuple())
Now when I first run the application and select a portion of text and change the font, it works correctly. But after that, whatever portion of text I am selecting and changing the font, it is ignoring the selection and applying the font on the whole text. Can anyone let me know what is the problem here?
IDLE uses tag_config to syntax color python code and it works on all Python versions and major OSes for the last 15 years.
To have some idea of why it seems to fail for you, you need to find an MCVE that fails. Start without tix and scrollbars. (Tix is deprecated in 3.6 and bugs are not being fixed.) Also notice that your code uses the same tag for each selection, so that when you change the configuration, it applies to all previous selections.
Here is simplified code that works as intended and expected.
import tkinter as tk
import time
root = tk.Tk()
text = tk.Text(root)
text.pack()
text.insert('1.0', "line 1\nline 2\nline 3\n")
text.tag_add('bg', '1.0', '1.4')
text.tag_config('bg', background='red')
root.update()
time.sleep(1)
text.tag_add('bg', '2.0', '2.4')
text.tag_config('bg', background='blue')
root.update()
You could try modifying it step by step until it either reproduces your problem or does what you want.
EDIT with example modification: use 'sel.first' and 'sel.last' instead of hard-coded indexes.
import tkinter as tk
import time
root = tk.Tk()
text = tk.Text(root)
text.pack()
text.insert('1.0', "line 1\nline 2\nline 3\n")
root.update() # make text visible for selection
input('select some text')
text.tag_add('bg', 'sel.first', 'sel.last')
text.tag_config('bg', background='red')
root.update() # make change visible
input('select some text')
text.tag_add('bg', 'sel.first', 'sel.last')
text.tag_config('bg', background='blue')
root.update() # make 2nd change visible
input('look at result')
Run in console. Move tk window so console and GUI are both visible. Make selection as prompted. Click on console* and hit return to allow input statement to return. Repeat. The result for me is that both selections, but not everything, turns blue. I suggest changing font instead of bg color for the next experiment.
On Windows, the selection highlighting in the tk windows disappears when one clicks on the console because Windows only allows visible selection in one window at a time. However, the select markers are still present in the text widget so that tag_add still works.

Tkinter Entry returns float values regardless of input

I have some pretty simple code right now that I am having issues with.
root = Tk()
label1 = Label(root, text ="Enter String:")
userInputString = Entry(root)
label1.pack()
userInputString.pack()
submit = Button(root,text = "Submit", command = root.destroy)
submit.pack(side =BOTTOM)
root.mainloop()
print(userInputString)
When I run the code everything operates as I would expect except
print(userInputString)
for an input asdf in the Entry print will return something like 0.9355325
But it will never be the same value back to back always random.
I am using python 3.5 and Eclipse Neon on a Windows 7 Machine.
Ultimately the goal is to accept a string from the user in the box that pops up and then be able to use that value as string later on. For example, it might be a file path that needs to be modified or opened.
Is Entry not the correct widget I should be using for this? Is there something inherently wrong with the code here? I am new to python and don't have a lot of strong programming experience so I am not even certain that this is set up right to receive a string.
Thanks in advance if anyone has any ideas.
There are two things wrong with your print statement. First, you print the widget, not the text in the widget. print(widget) prints str(widget), which is the tk pathname of the widget. The '.' represents the root window. The integer that follows is a number that tkinter assigned as the name of the widget. In current 3.6, it would instead be 'entry', so you would see ".entry".
Second, you try to print the widget text after you destroy the widget. After root.destroy, the python tkinter wrapper still exists, but the tk widget that it wrapped is gone. The following works on 3.6, Win10.
import tkinter as tk
root = tk.Tk()
label = tk.Label(root, text="Enter String:")
entry = tk.Entry(root)
def print_entry(event=None):
print(entry.get())
entry.bind('<Key-Return>', print_entry)
entry.focus_set()
submit = tk.Button(root, text="Submit", command=print_entry)
label.pack()
entry.pack()
submit.pack()
root.mainloop()
Bonus 1: I set the focus to the entry box so one can start typing without tabbing to the box or clicking on it.
Bonus 2: I bound the key to the submit function so one can submit without using the mouse. Note that the command then requires an 'event' parameter, but it must default to None to use it with the button.
The NMT Reference, which I use constantly, is fairly complete and mostly correct.

Closing a Tkinter Entry Box in Python

I am trying to create a simple popup text entry for the user in which a user enters a text and hits submit (a button). Upon clicking submit, I want the popup entry box to close off and continue on with the rest of the code. Following is a sample code for display that I borrowed from an old post here:
from Tkinter import *
root = Tk()
nameLabel = Label(root, text="Name")
ent = Entry(root, bd=5)
def getName():
print ent.get()
submit = Button(root, text ="Submit", command = getName)
nameLabel.pack()
ent.pack()
submit.pack(side = BOTTOM)
root.mainloop()
print "Rest of the code goes here"
I don't have much experience with Tkinter so I am not sure where and how exactly to call the appropriate functions for closing the entry box after the user hits 'Submit'. My guess is it would have to be inside the getName() function?
If I understand you correctly, then all you need to do is call the root window's destroy method at the end of the getName function:
def getName():
print ent.get()
root.destroy()
Doing so is equivalent to manually clicking the X button in the corner of the window.
Alternate method:
since there isn't much to your popup you could also eliminate several lines of code in your GUI, save some CPU and get pretty much the same output with this:
submitvariablename=raw_input('Please enter a Name')
same functionality and much faster, cleaner.
Just a thought.

Python - TKinter - Editing Widgets

I need a widget in TKinter to be a global widget, however, I need the text displayed in it to be different every time. I'm quite new with TKinter and haven't yet successfully managed to edit an option in a widget.
I assume it's something to do with widget.add_option() but the documentation is quite confusing to me and I can't figure out the command.
I specifically just need to edit the text = "" section.
Thanks
EDIT:
gm1_b_current_choice_label = Label(frame_gm1_b, text = "Current input is:\t %s"% str(save_game[6]))
I specifically need to update the save_game[6] (which is a list) in the widget creation, but I assume once the widget is created that's it. I could create the widget every time before I place it but this causes issues with destroying it later.
You can use the .config method to change options on a Tkinter widget.
To demonstrate, consider this simple script:
from Tkinter import Tk, Button, Label
root = Tk()
label = Label(text="This is some text")
label.grid()
def click():
label.config(text="This is different text")
Button(text="Change text", command=click).grid()
root.mainloop()
When the button is clicked, the label's text is changed.
Note that you could also do this:
label["text"] = "This is different text"
or this:
label.configure(text="This is different text")
All three solutions ultimately do the same thing, so you can pick whichever you like.
You can always use the .configure(text = "new text") method, as iCodez suggested.
Alternatively, try using a StringVar as the text_variable parameter:
my_text_var = StringVar(frame_gm1_b)
my_text_var.set("Current input is:\t %s"% str(save_game[6]))
gm1_b_current_choice_label = Label(frame_gm1_b, textvariable = my_text_var)
Then, you can change the text by directly altering my_text_var:
my_text_var.set("Some new text")
This can be linked to a button or another event-based widget, or however else you want to change the text.

Python, Tkinter: How to redirect the output of a function to a notebook tab?

I am wondering if it is possible to redirect the output of a function to a tab in the ttk notebook widget.
I assumed it would be similar to the listbox widget where you just used listbox.insert but I can not get this to work.
I apologize if this is a simple question but its really stumped me and I am unable to find any helpful material online to help me.
thanks in advance
Im using python 3.3
The Insert function works almost the same, the only difference is instead of taking a string it takes a frame. Add is a lot simpler though, you don't need to specify an index it just adds it to the end. All you need to do is create a frame, pack a Text element into it, and then pack the whole thing into the notebook. It would look something like this
noteb = ttk.Notebook( root, width=500, height=300 )
frame1 = tkinter.Frame( noteb )
textbox = tkinter.Text( frame1, put whatever you want to put here )
frame1.pack( expand=1, fill='both' )
noteb.add( frame1, whatever parameters you want )
noteb.pack( expand=1, fill='both' )
You should then be able to change the text in textbox directly.
Depends somewhat on what type of widgets you use as tabs, but basically it shouldn't be very different. Just keep track of your tab widgets and call the appropriate method.
Example with two Text tabs:
from Tkinter import *
from ttk import Notebook
def addText(tab):
tab.insert(END, "foo! ")
root = Tk()
nb = Notebook(root, height=240, width=480)
tabs = {"foo": [], "bar": []}
for tabname in tabs:
tab = Text(nb)
tabs[tabname] = tab
nb.add(tab, text= tabname)
nb.pack()
Button(root, text= "Add text!", command = lambda: addText(tabs["foo"])).pack()
root.mainloop()
Clicking the "Add text!" button appends some text to the first tab.

Categories

Resources