entry.get() shell/idle output issue - python

Okay so I'm trying to learn some GUI using tkinter following along this website's guide: https://realpython.com/python-gui-tkinter/#building-your-first-python-gui-application-with-tkinter
Depending on how I run the code it works using IDLE verse shell.
What happens in Idle is it is calling name long before anything is ever actually typed in the entry. which is why the output is "" . Where in shell I can type something into the entry "john doe" and when I get to 'name' it has something it can output.
import tkinter as tk
window = tk.Tk()
label = tk.Label(text = "Name")
entry = tk.Entry()
label.pack()
entry.pack()
name = entry.get()
name

Typically you would create a button that initiates the .get and start the mainloop for the window, like this:
import tkinter as tk
def print_entry(widget):
name = widget.get()
print(name)
window = tk.Tk()
label = tk.Label(text = "Name")
entry = tk.Entry()
button = tk.Button(text = "Get Entry",
command = lambda e = entry: print_entry(e))
label.pack()
entry.pack()
button.pack()
window.mainloop()

Related

How to get a user input in entry widget without button in tkinter python?

from tkinter import *
root = Tk()
label = Label(root, text="Name:")
label.pack()
e = Entry(root)
e.pack()
root.mainloop()
How do I get a user input in entry widget without button in tkinter?
window = tk.Tk()
username = tk.Entry(window)
username.pack()
def it_has_been_written(*args):
#what you want to execute when user starts typing something
pass
username.trace_add("write", it_has_been_written)
window.mainloop()
To see more about this https://tkdocs.com/tutorial/widgets.html

Tkinter how to lock Text widget by checking checkbox?

I am new to programming and Tkinter. I want to DISABLED textbox when checkbox is pressed and open it NORMAL when box is not ticked. Here is my code:
from tkinter import *
root = Tk()
def lock_fields():
if check == True:
data.configure(state=DISABLED)
if check == False:
data.configure(state=NORMAL)
check = BooleanVar()
open_for_edit = Checkbutton(root, text="check the box for editing", variable=check,
onvalue=True, offvalue=False, command=lambda: lock_fields())
open_for_edit.pack()
check = check.get()
data = Text(root)
data.insert(END, "I would like to be able to edit this text only when checkbox is checked.")
data.pack()
root.mainloop()
It seems that for some reason the check-variable is always False when it enters to lock_fields function. I tried passing check argument to the method.
You're pretty close, only thing is that the check.get() line must be in the function. Also you don't need the lambda. Try this:
from tkinter import *
root = Tk()
def lock_fields():
if check.get():
data.configure(state=DISABLED)
else:
data.configure(state=NORMAL)
check = BooleanVar()
open_for_edit = Checkbutton(root, text="check the box for editing", variable=check, onvalue=True, offvalue=False, command=lock_fields)
open_for_edit.pack()
data = Text(root)
data.insert(END, "I would like to be able to edit this text only when checkbox is checked.")
data.pack()
root.mainloop()

Problem when defining a function in python with tkinter

Im making a program that searches a website for a specific word.
Exampel : Word: football on the website fifa.com.
I made it in a terminal which was very easy. Now i want to make a program using tkinter and it wont work.
The problem i have is when i run my program it says
File "c:/Users/Censored/Desktop/PythonFolder/Program.py", line 22, in
temp = Button(root, text='GO', command=searchgo)
NameError: name 'searchgo' is not defined
This is my code:
import requests
import re
from tkinter import *
root = Tk()
root.title('WordCounter')
root.configure(bg='#2f3136')
root.geometry('700x700')
root.resizable(False, False)
# Buttons
e1 = Entry(root, width='35')
label1 = Label(root, text='Write The Word You Want To Search For', bg='#2f3136', fg='white',)
e2 = Entry(root, width='35')
label2 = Label(root, text='Write the websites URL', bg='#2f3136', fg='white',)
temp = Button(root, text='GO', command=searchgo)
# Buttons on screen
label1.grid(row='1', column='1',padx='10')
e1.grid(row='2', column='1', padx='10')
label2.grid(row='1', column='2', padx='10')
e2.grid(row='2', column='2', padx='10')
temp.pack()
# Define Functions
def searchgo():
word = e1.get()
URL = e2.get()
page = requests.get(URL).text
print(page.find(word))
root.mainloop()
Thanks for helping me!
Your code has couple of bugs,
Define the function searchgo before you assign the callback to your button
In this code, better use grid to place you button instead of place or you get the following error
cannot use geometry manager pack inside . (root) which already has slaves managed by grid
The reason of this error is that, you cannot use pack and grid geometry managers inside the same master window (root in this program). Since you have used grid for most of the widgets, use grid for placing the button also.
Also, in case you are not aware, in grid geometry manager row and column position values start at 0 and not 1
Here is the code:
import requests
import re
from tkinter import *
root = Tk()
root.title('WordCounter')
root.configure(bg='#2f3136')
root.geometry('700x700')
root.resizable(False, False)
# Buttons
e1 = Entry(root, width='35')
label1 = Label(root, text='Write The Word You Want To Search For', bg='#2f3136', fg='white',)
e2 = Entry(root, width='35')
label2 = Label(root, text='Write the websites URL', bg='#2f3136', fg='white',)
# Define Functions
def searchgo():
word = e1.get()
URL = e2.get()
page = requests.get(URL).text
print(page.find(word))
temp = Button(root, text='GO', command=searchgo)
# Buttons on screen
label1.grid(row='0', column='0',padx='10')
e1.grid(row='1', column='0', padx='10')
label2.grid(row='0', column='1', padx='10')
e2.grid(row='1', column='1', padx='10')
# use the grid manager to place your button
temp.grid(row='1', column='2', padx='10')
root.mainloop()
I have tried explaining the changes I made with some theory. I hope you understand!
Should the function be defined before you assigne it as Button attribute?
This will raise same exception:
class A:
def __init__(self, something):
self.something = something
a = A(func)
def func():
return
But, this works as expected:
def func():
return
class A:
def __init__(self, something):
self.something = something
a = A(func)

Opening a new window using tkinter button

As you can see on my code I'm trying to open a new window with a button. Window opens but welcome message isn't showing like the way that I want.
It shows Welcome PY_VAR0 PY_VAR1. But I would like to show a name.
I've tried using return command to return variables from getvalue() function but it doesn't work.
def getvalue():
name.get()
surname.get()
def newwindow():
window.destroy()
window2 = tk.Tk()
label3 = tk.Label(text="Welcome {} {}".format(name,surname)).grid()
window2.mainloop()
button = tk.Button(window,text="Submit",command=getvalue and newwindow).grid(row=3,column=1)
window.mainloop()
I would like to open a new window with a welcome message.
You have to use .get() to get value from StringVar, IntVar, etc - name.get(), surname.get()
label3 = tk.Label(text="Welcome {} {}".format(name.get(), surname.get()))
label3.grid()
And remeber: To set value you will have to use variable.set(value) instead of variable = value
BTW: you have big mistake in this line (and others)
label3 = tk.Label(..).grid(..)
It assign None to label3 because grid()/pack()/place() return None
You have to do it in two steps
label3 = tk.Label(..)
label3.grid(..)
You can use messagebox to open a new window as well as print a welcome message. it is really simple.
from tkinter import Tk, Button
# Make sure to import messagebox like this, otherwise you might get issues
import tkinter.messagebox
def messagebox():
tkinter.messagebox.showinfo('title','Welcome!')
def main():
width, height = 500, 500
root = Tk()
root.geometry(f'{width}x{height}')
root.title('My window')
button = Button(root, width=150, height=70, command=messagebox)
button.pack()
root.mainloop()
if __name__ == "__main__":
main()
Please import messagebox the way it is shown, I am not sure why but tkinter does not like other ways.
What happens when you print(name + " " + surname)?
If those variables have the correct values maybe you should try rewriting your script a couple different ways, for example:
labelText = "Welcome " + name + " " + surname
label3 = tk.Label(text=labelText)

How to get the entry text and display in another entry?

I just want that when I type my name inside the entry box then appears in another entry with some add text. The idea is type in the entry below and after that it showed in the big entry.I was looking for this solution, but just found place in Label. I don't want in Label. The window is more big, must drag to show the entry. There's is a picture that i use in this script:
from tkinter import *
from PIL import Image, ImageTk
root = Tk()
cat = Entry(root)
cat.place(x=48, y=25, width= 350, height=140)
user = Entry(root)
user.place(x=75, y=550)
btn = Button(root, text='START')
btn.place(x=220, y=410)
root.mainloop()
#
Ok, It works the way you told me,thank you!
But now i'm facing another problem.
The problem is when i insert the function of the game in the second window. I tested in one window and it works, but when i place the function in the second window gives an error when i press the "Start" button:
'''user_try = int(txt.get())
NameError: name 'txt' is not defined'''
When i press reset button gives another error:
'''user_try = int(txt.get())
NameError: name 'txt' is not defined'''
So i know that is missing definition, but i don't know how to make a reference for this command that it's in the second window. Like i said running with just one window the program works.
Maybe i should make using class, i don't know, but i wish to make this way that i started. However if there's no other way to do as i'm doing, let's go.
I just simplify the script here, actualy the main script is more bigger, so my idea is when open the program, there is a window and the user read the instructions about the game and proceed open the second window. The window have pictures and some hidden buttons in the next picture, so there will be an interactivity with the environment.
The guess number is just the beggining. After that there will be new challeges.
I'm very excited doing this, but i'm stuck in this point. The part one i finished, the pictures, the hidden buttons it's exacly the way i want, but the challenge stops here in this problem.
from tkinter import *
from PIL import Image, ImageTk, ImageSequence
import random
from tkinter import messagebox
pc = random.randint(1,10)
def reset():
global pc
pc = random.randint(1,10)
cat['text'] = 'Ok! Lets Try Again!'
def openwin2():
win1.withdraw()
win2 = Toplevel()
win2.geometry('350x300+180+100')
win2.title('second window')
txt = Entry(win2)
txt.place(x=10,y=10)
cat = Label(win2,wraplength=300)
cat.place(x=10,y=50)
cat.config(text='Hi! I Am thinking a number between 1 and 10.')
btn = Button(win2,text='start',command=check)
btn.place(x=30, y=150)
btn2 = Button(win2, text='reset', command=reset)
btn2.place(x=110,y=150)
win2.mainloop()
def check():
user_try = int(txt.get())
if user_try < pc:
msg = 'Hmmmm... the number, which I thought of, is greater than this.'
elif user_try > pc:
msg = 'How about trying a smaller number ?!'
elif user_try == pc:
msg = 'Well Done! You guessed! It was %s the number!' % user_try
else:
msg = 'Something Went Wrong...'
cat['text'] = msg
win1 = Tk()
win1.title('First Window')
win1.geometry('350x300')
user = Label(win1,text='first window')
user.place(x=10,y=10)
btn1 = Button(win1,text='Open Window 2', command=openwin2)
btn1.place(x=10,y=50)
win1.mainloop()
There are multiple ways to do this in tkinter, here's a rework of your code using StringVar objects set to the textvariable properties of your Entry objects:
import tkinter as tk
def doit():
out_string.set("Hello " + in_string.get())
root = tk.Tk()
in_string = tk.StringVar()
out_string = tk.StringVar()
cat = tk.Entry(root, textvariable=in_string)
cat.place(x=20, y=25, width=100)
user = tk.Entry(root, textvariable=out_string)
user.place(x=20, y=75)
btn = tk.Button(root, text='START', command=doit)
btn.place(x=20, y=150)
root.mainloop()
Per #Mike-SMT, here's a different approach using Entry.get() and Entry.insert(). It augments the text when the user clicks the button:
import tkinter as tk
def doit():
user.insert(tk.END, cat.get())
root = tk.Tk()
cat = tk.Entry(root)
cat.place(x=20, y=25, width=100)
user = tk.Entry(root)
user.place(x=20, y=75)
user.insert(0, "Hello ")
btn = tk.Button(root, text='START', command=doit)
btn.place(x=20, y=150)
root.mainloop()
However, you'll see that subsequent button clicks keep appending the text. When working with Entry.insert(), you need to work with Entry.delete() and/or other Entry methods to properly manipulate the text.

Categories

Resources