So I am trying to when the person clicks on the button I created, to display the text they wrote on the input field but for some reason when I click the button it displays:
.!entry
And I don't know what I am doing wrong since I am new to python so I wanted to know how to fix this problem, here's my code and thank you since any help is appreciated!
from tkinter import *
screen = Tk()
def print_input():
text2 = Label(screen, text=input_field)
text2.grid(row=1, columnspan=3)
text = Label(screen, text="Write to print:")
text.grid(row=0, column=0)
input_field = Entry(screen)
input_field.grid(row=0, column=1)
submit_button = Button(screen, text="Print!", fg="yellow", bg="purple",
command=print_input)
submit_button.grid(row=0, column=2)
screen.mainloop()
Change:
def print_input():
text2 = Label(screen, text=input_field)
to:
def print_input():
text2 = Label(screen, text=input_field.get())
# ^^^^^^
You're telling the text of the label to be set to the Entry widget instead of the Entry widget's content. To get the content of the Entry widget, use the .get() method.
The funky string you're seeing in the label is the tkinter name for the Entry widget.
Related
Hello I'm a few weeks into python and I'm now starting learning tkinter. The button should have the text Say hello and when the user clicks the button, the bottom label should display the name with Hi in front of it. However I cannot get the label to display "Hi {name}". Could someone help me?
from tkinter import *
from tkinter.ttk import *
def process_name():
"""Do something with the name (in this case just print it)"""
global name_entry
print("Hi {}".format(name.get()))
def main():
"""Set up the GUI and run it"""
global name_entry
window = Tk()
name_label = Label(window, text='Enter name a name below:')
name_label.grid(row=0, column=0)
name_entry = Entry(window)
name_entry.grid(row=1, column=3)
button = Button(window, text='Say hello', command=process_name, padding=10)
button.grid(row=1, column=0, columnspan=2)
window.mainloop()
main()
I've tried using set() but it doesn't display.
Thank you.
This should work for your needs. Make sure to read the code comments to understand what I did properly.
Few points though,
Not recommended to use wildcard import like from tkinter import * . The reason is simple. both tkinter and tkinter.ttk have common classes and functions like Button, Label and more. It becomes ambiguous for interpreter to decide which ones to use.
use .config() or .configure() to update labels, buttons, entries or text widgets in tkinter. Like I did in code below.
Your code modified
from tkinter import *
from tkinter.ttk import *
def process_name():
"""Do something with the name (in this case just print it)"""
global name_entry # this will print hi {name} to terminal.
print("Hi {}".format(name_entry.get()))
global nameLabel # to change'the label with hi{name} text below the button.
nameLabel.configure(text=f'Hi {name_entry.get()}')
def main():
"""Set up the GUI and run it"""
global name_entry, nameLabel
window = Tk()
name_label = Label(window, text='Enter name a name below:')
name_label.grid(row=0, column=0)
name_entry = Entry(window)
name_entry.grid(row=1, column=3)
button = Button(window, text='Say hello', command=process_name, padding=10)
button.grid(row=1, column=0, columnspan=2)
# I defined a label BELOW the button to show how to change
nameLabel = Label(window, text=' ') # an empty text Label
nameLabel.grid(row=2)
window.mainloop()
main()
I am trying to place a greyed out background text inside a textbox, that disappears when someone begins to type. I have tried overlaying a label onto the textbox, but I could not get it to work. Here is some code I am running for the text box
root = tk.Tk()
S = tk.Scrollbar(root)
T = tk.Text(root, height=70, width=50)
S.pack(side=tk.RIGHT, fill=tk.Y)
T.pack(side=tk.LEFT, fill=tk.Y)
S.config(command=T.yview)
T.config(yscrollcommand=S.set)
root.protocol("WM_DELETE_WINDOW", stop)
tk.mainloop()
How can I put in the background text?
Using a callback function you can remove the default text and change the foreground colour
import tkinter as tk
root = tk.Tk()
e = tk.Entry(root, fg='grey')
e.insert(0, "some text")
def some_callback(event): # must include event
e.delete(0, "end")
e['foreground'] = 'black'
# e.unbind("<Button-1>")
e.unbind("<FocusIn>")
return None
# e.bind("<Button-1>", some_callback)
e.bind("<FocusIn>", some_callback)
e.pack()
root.mainloop()
You are probably talking about placeholders , tkinter does not have placeholder attribute for Text widget, but you do something similar with Entry widget . You have to do it manually, by binding an event with the Text widget.
text = tk.StringVar()
text.set('Placeholder text')
T = tk.Entry(root, height=70, width=50, textvariable = text)
def erasePlaceholder(event):
if text.get() == 'Placeholder text':
text.set('')
T.bind('<Button-1>', erasePlaceholder)
Try to ask if you face any issues.
I need to create a field in tkinter that stores an emoji but when someone presses a button, that emoji is overwritten. I can't get emojis working in tkinter and I'm not sure how to then overwrite it.
import tkinter as tk
self.option4 = tk.Button(self, width=10)
self.option4["text"] = "no"
self.option4["command"] = self.wrong
self.option4.pack(side="top")
corecalc = "🔲"
self.answercheck = tk.Text(self, height=1, width=5)
self.answercheck.pack()
self.answercheck.insert(tk.END, corecalc)
self.QUIT = tk.Button(self, text="Quit", fg="red", command=root.destroy)
self.QUIT.pack(side="bottom")
def correct(self):
corecalc = "✅"
def wrong(self):
corecalc = "❌"
Expected 🔲 outputs in field and changes to ❌ upon button press. Also is there a better method than text box that makes the field fixed rather than editable by end user.
Error: _tkinter.TclError: character U+1f532 is above the range (U+0000-U+FFFF) allowed by Tcl
You can use any tkinter widget to display the characters - emojis or otherwise, that you will need - a Text widget if you want to display a single character is a poor choice, though possible.
If you really want to use Text, you can change it to not editable by setting its state Key to "disabled" (as oposed to the default "normal"):
self.answercheck = tk.Text(self, height=1, width=5, state="disabled")
A text box will require you to remove the previous text before insertig the new, you can simply use a tkinter.Label widget if you want programtic only changes to the characters:
import tkinter as tk
w = tk.Tk()
display = tk.Label(w, text="□")
display.pack()
def correct():
display["text"] = "✅"
def wrong():
display["text"] = "❌"
button = tk.Button(w, text="no", command=wrong)
button.pack()
button = tk.Button(w, text="yes", command=correct)
button.pack()
tkinter.mainloop()
(In the build I have here - Python 3.7 on a Linux fedora, tkinter can't handle your 🔲 character directly, as its codepoint is above \uffff)
I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()
I'm trying to use an Entry field to get manual input, and then work with that data.
All sources I've found claim I should use the get() function, but I haven't found a simple working mini example yet, and I can't get it to work.
I hope someone can tel me what I'm doing wrong. Here's a mini file:
from tkinter import *
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
content = entry.get()
print(content) # does not work
mainloop()
This gives me an Entry field I can type in, but I can't do anything with the data once it's typed in.
I suspect my code doesn't work because initially, entry is empty. But then how do I access input data once it has been typed in?
It looks like you may be confused as to when commands are run. In your example, you are calling the get method before the GUI has a chance to be displayed on the screen (which happens after you call mainloop.
Try adding a button that calls the get method. This is much easier if you write your application as a class. For example:
import tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.entry = tk.Entry(self)
self.button = tk.Button(self, text="Get", command=self.on_button)
self.button.pack()
self.entry.pack()
def on_button(self):
print(self.entry.get())
app = SampleApp()
app.mainloop()
Run the program, type into the entry widget, then click on the button.
You could also use a StringVar variable, even if it's not strictly necessary:
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set("a default value")
s = v.get()
For more information, see this page on effbot.org.
A simple example without classes:
from tkinter import *
master = Tk()
# Create this method before you create the entry
def return_entry(en):
"""Gets and prints the content of the entry"""
content = entry.get()
print(content)
Label(master, text="Input: ").grid(row=0, sticky=W)
entry = Entry(master)
entry.grid(row=0, column=1)
# Connect the entry with the return button
entry.bind('<Return>', return_entry)
mainloop()
*
master = Tk()
entryb1 = StringVar
Label(master, text="Input: ").grid(row=0, sticky=W)
Entry(master, textvariable=entryb1).grid(row=1, column=1)
b1 = Button(master, text="continue", command=print_content)
b1.grid(row=2, column=1)
def print_content():
global entryb1
content = entryb1.get()
print(content)
master.mainloop()
What you did wrong was not put it inside a Define function then you hadn't used the .get function with the textvariable you had set.
you need to put a textvariable in it, so you can use set() and get() method :
var=StringVar()
x= Entry (root,textvariable=var)
Most of the answers I found only showed how to do it with tkinter as tk. This was a problem for me as my program was 300 lines long with tons of other labels and buttons, and I would have had to change a lot of it.
Here's a way to do it without importing tkinter as tk or using StringVars. I modified the original mini program by:
making it a class
adding a button and an extra method.
This program opens up a tkinter window with an entry box and an "Enter" button. Clicking the Enter button prints whatever is in the entry box.
from tkinter import *
class mini():
def __init__(self):
master = Tk()
Label(master, text="Input: ").grid(row=0, sticky=W)
Button(master, text='Enter', command=self.get_content).grid(row=1)
self.entry = Entry(master)
self.entry.grid(row=0, column=1)
master.mainloop()
def get_content(self):
content = self.entry.get()
print(content)
m = mini()