I can't use the text from my Entry widget - python-3.x

There is something in my code that isn't letting me use the text from my Entry widget. I want to use the text a user will enter in my Entry widget, which i've called "textentry", in another part of my code but it doesn't seem to be storing it in a way i can use. In this example i'm just trying to print what is entered into the terminal.
I can get it to print if i uncomment the "print(textentry.get())" in my function.
As it is now i get ".!entry" printed in the terminal. i'm not sure I follow that output either.
I feel like it's probably something simple but i've been struggling a while and many different approaches but still not success.
import tkinter as tk
from tkinter import *
def click():
textentry.get()
# print(textentry.get())
Text_input_window.destroy()
Text_input_window= Tk()
Label (Text_input_window,text="Enter search word:", bg="black", fg="white").grid(row=1, column=0, sticky=W)
textentry = tk.Entry(Text_input_window, width=20, bg="white")
textentry.grid(row=2, column=0, sticky=W)
Button(Text_input_window, text="SUBMIT", width=6, command=click).grid(row=3, column=0, sticky=W)
Text_input_window.mainloop()
print(textentry)

Try it:
import tkinter as tk
from tkinter import *
Text_input_window = Tk()
textentry = StringVar()
def click():
global textentry
textentry = textentry_ent.get()
# print(textentry.get())
Text_input_window.destroy()
Label(Text_input_window, text="Enter search word:",
bg="black", fg="white").grid(row=1, column=0, sticky=W)
textentry_ent = tk.Entry(Text_input_window, textvariable=textentry,width=20, bg="white")
textentry_ent.grid(row=2, column=0, sticky=W)
Button(Text_input_window, text="SUBMIT", width=6,
command=click).grid(row=3, column=0, sticky=W)
Text_input_window.mainloop()
print(textentry)

Related

How to show two Frames side by side in Tkinter

This is what I got
This is what I want to get
I've tried it like 2 hours with reading the documentation and every tutorial I could possibly find but after all I'm not able to display two ttk.Frames side by side with a border around them.
What have I done wrong?
This is my code so far (and yeah, I know, I've never used self.path but I just like to have it available in need):
import os
import tkinter as tk
import tkinter.ttk as ttk
from ttkthemes import ThemedTk
class GUI(ThemedTk):
def __init__(self):
super().__init__()
self.set_theme("breeze")
self.path = os.path.dirname(__file__)
self.title("Kniffel All In One")
self.defineVariables()
# Root Window
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=5)
self.columnconfigure(1, weight=1)
self.LeftFrame = ttk.Frame(self, border=True, borderwidth=1)
self.LeftFrame.grid(row=0, column=0, padx=5, pady=5, sticky="NSWE")
self.RightFrame= ttk.Frame(self, border=True, borderwidth=1)
self.RightFrame.grid(row=0, column=1, padx=5, pady=5, sticky="NSWE")
# LeftFrame
self.LeftEntry = ttk.Entry(self.LeftFrame, textvariable=self.text1).grid(row=0, column=0, ipadx=5, ipady=5, sticky="WE")
self.LeftLabel = ttk.Label(self.LeftFrame, text="Little test left side").grid(row=1, column=0, ipadx=5, ipady=5, sticky="WE")
# RightFrame
self.RightEntry = ttk.Entry(self.RightFrame, textvariable=self.text2).grid(row=0, column=0, ipadx=5, ipady=5, sticky="WE")
self.RightLabel = ttk.Label(self.RightFrame, text="Litte test right side").grid(row=1, column=0, ipadx=5, ipady=5, sticky="WE")
self.mainloop()
def defineVariables(self):
self.text1 = tk.StringVar()
self.text2 = tk.StringVar()
if __name__ == '__main__':
GUI()
Note that I didn't use .pack() and .grid() together and it doesn't display a border even though I thought border=True would show one.
Please be so kind to just answer my question since I haven't ask for aesthetics, readability or programming style improvements. Also this won't be a professional application.
Thanks for understanding this.

Confused about binding the enter key in tkinter

This is a search bar program and once enter is hit it will open google with whatever I searched:
import tkinter as tk
from tkinter import ttk
import webbrowser
root = tk.Tk()
root.title("Search Bar")
label1 = ttk.Label(root, text="Query")
label1.grid(row=0, column=0)
entry1 = ttk.Entry(root, width=50)
entry1.grid(row=0, column=1)
def callback():
webbrowser.open("http://google.com/search?q="+entry1.get())
def get(event):
webbrowser.open("http://google.com/search?q=" + entry1.get())
button1 = ttk.Button(root, text="Search", width=10, command=callback)
button1.grid(row=0, column=2)
entry1.bind("<Return>", get)
root.mainloop()
What I'm most confused about is why did I need a second function [get(event)] in order to bind the enter key at entry1.bind("<Return>", get). Why couldn't I just put entry1.bind("<Return>", callback) (which is for the button). For some reason, the enter bind function requires a parameter and I'd just like an explanation as to why that is? Even though whatever is in the parameter is not being called.
You can use event=None in
def callback(event=None):
and then you can use with command= and bind()
bind() will run it with event, command= will run it without event and it will use None
import tkinter as tk
from tkinter import ttk
import webbrowser
def callback(event=None):
webbrowser.open("http://google.com/search?q="+entry1.get())
root = tk.Tk()
root.title("Search Bar")
label1 = ttk.Label(root, text="Query")
label1.grid(row=0, column=0)
entry1 = ttk.Entry(root, width=50)
entry1.grid(row=0, column=1)
button1 = ttk.Button(root, text="Search", width=10, command=callback)
button1.grid(row=0, column=2)
entry1.bind("<Return>", callback)
root.mainloop()
bind() can be used with different events and objects so it send this information to function - ie. event.widget - so you can bind the same function to different objects.
def callback(event=None):
print(event)
if event: # if not None
print(event.widget)
You can use
def callback(event=None):
Or u can pass None as parameter
import tkinter as tk
from tkinter import ttk
import webbrowser
root = tk.Tk()
root.title("Search Bar")
label1 = ttk.Label(root, text="Query")
label1.grid(row=0, column=0)
entry1 = ttk.Entry(root, width=50)
entry1.grid(row=0, column=1)
def callback():
webbrowser.open("http://google.com/search?q="+entry1.get())
def get(event):
webbrowser.open("http://google.com/search?q=" + entry1.get())
button1 = ttk.Button(root, text="Search", width=10, command=lambda x=None:get(x))
button1.grid(row=0, column=2)
entry1.bind("<Return>", get)
root.mainloop()

Updating or reseting a tkinter display

I'm working on a small Tkinter program where once started it prompts you to input a name then after clicking submit it will display "Welcome to my world". I'm having issues with either retrieving the input and displaying it in a new window or updating the window with the new information but it displays Py_Var1 as the entry name. What am I doing wrong, is it because I'm trying to display information in a new window or am I using the functions wrong?
Here is my code
from tkinter import *
root = Tk()
#Functions
def info():
a= entry_1.get()
def close_window(root):
root.destroy()
def comb(event=None):
info()
close_window(root)
#Display
input_1 = Label(root, text=" Name: ", bg= "light grey", fg="blue", font=("Arial", 16))
entry_1 = Entry(root, bg= "white", fg= "black", bd= 5, relief= SUNKEN, font=("Arial", 12))
button = Button(root, text="Submit", command=comb, bd= 6, relief= RAISED, fg='blue', font=("Arial", 12))
root.bind("<Return>", comb)
aVar = StringVar(entry_1.get())
aVar.set(aVar)
#entry display
input_1.grid(row=1, sticky=E)
entry_1.grid(row=1, column=1)
button.grid(row=3, column=1)
root.mainloop()
##Second Window
root = Tk()
Var = StringVar()
Var.set(info)
t1 = Label(root, text="Welcome")
t2 = Label(root, text= Var)
t3 = Label(root, text="to my world")
#Display
t1.grid(row=1, column=1)
t2.grid(row=1, column=2)
t3.grid(row=1, column=3)
root.mainloop()
I think the problem was that you were trying to access a variable which you assigned before you destroyed the window after it was destroyed which Tkinter can't do. Needed a global variable. Your code should work now.
from tkinter import *
root = Tk()
#Functions
def info():
global a
a= entry_1.get()
def close_window(root):
root.destroy()
def comb(event=None):
info()
close_window(root)
#Display
input_1 = Label(root, text=" Name: ", bg= "light grey", fg="blue", font=("Arial", 16))
entry_1 = Entry(root, bg= "white", fg= "black", bd= 5, relief= SUNKEN, font=("Arial", 12))
button = Button(root, text="Submit", command=comb, bd= 6, relief= RAISED, fg='blue', font=("Arial", 12))
root.bind("<Return>", comb)
#entry display
input_1.grid(row=1, sticky=E)
entry_1.grid(row=1, column=1)
button.grid(row=3, column=1)
root.mainloop()
##Second Window
root = Tk()
t1 = Label(root, text="Welcome "+str(a)+" to my world")
##t2 = Label(root, text= Var)
##t3 = Label(root, text="to my world") # cleaner this way
#Display
t1.grid(row=1, column=1)
#t2.grid(row=1, column=2)
#t3.grid(row=1, column=3)
root.mainloop()
It is not running because there are many errors and no logic.
You use many functions whithout reason and none of them returns values.
Also, you destroy the Entry widget closing the root window and after that
you are asking to get the text from the Entry you just destroyed using a function which don't return anything. Even if you don't destroy the root window and use a toplevel window, still this program will not work because your function don't return anything.
It looks like you don't understand the basic usage of functions. Consider to play with functions with simple programs before try something more complicated.

How to create a sub frames with a specific layout?

I'm aiming to make a login program but the only part that confuses me is how to make the frames.I need 3 different frames but I neither know how to make a frame other the then like this:
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
and I can only make labels and widgets using that single mainframe. As far as making another one, it is beyond me. I need to know exactly place widets inside of each frame and even after creating frames I don't know how to place stuff on the grid. Would I go for the overall grid, or does something change after making the grid. I'm using the following layout for making the frame. Basically i'm hoping for a crash course in frames. Any information i've gathered doesn't make sense to me, even after I tried to put it into code.
I've got the coding part down just not the frame part.
#Import tkinter to make gui
from tkinter import *
from tkinter import ttk
import codecs
def login(*args
):
file = open("rot13.txt", "r")
lines = file.readlines()
uname = user.get()
pword = pw.get()
for i in lines:
x = i.split()
if codecs.encode(uname,'rot13') == x[0] and codecs.encode(pword,'rot13') == x[1]:
result.set("Successful")
break;
else:
result.set("Access Denied")
root = Tk()
root.title("Login")
#Configures column and row settings and sets padding
mainframe = ttk.Frame(root, padding="3 3 12 12")
mainframe.grid(column=0, row=0, sticky=(N, W, E, S))
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
user = StringVar()
pw = StringVar()
result = StringVar()
user_entry = ttk.Entry(mainframe, width=20, textvariable=user)
user_entry.grid(column=2, row=1, sticky=(W, E))
pw_entry = ttk.Entry(mainframe, width=20, textvariable=pw)
pw_entry.grid(column=2, row=2, sticky=(W, E))
ttk.Label(mainframe, text="Username ").grid(column=1, row=1, sticky=W)
ttk.Label(mainframe, text="Password ").grid(column=1, row=2, sticky=W)
ttk.Label(mainframe, text="").grid(column=1, row=3, sticky=W)
ttk.Label(mainframe, text="Result").grid(column=1, row=4, sticky=W)
ttk.Label(mainframe, text="").grid(column=1, row=5, sticky=W)
ttk.Button(mainframe, text="Login", command=login).grid(column=3, row=6, sticky=W)
#Makes a spot to put in result
ttk.Label(mainframe, textvariable=result).grid(column=2, row=4, sticky=(W, E))
#Opens up with item selected and allows you to enter username without having to click it
user_entry.focus()
#Runs calculate if click enter
root.bind('<Return>', login)
root.mainloop()
I believe the key point that you are missing is that subframes of mainframe use mainframe as the parent and that widgets within subframes use the subframe as parent. Furthermore, you can then place the subframe within the mainframe and the subframe widgets within the subframe. You do not have to pass parents to .grid because each widget knows its parent. A simplified example:
from tkinter import *
root = Tk()
mainframe = Frame(root)
login = Frame(mainframe)
label = Label(login, text='label')
entry = Entry(login)
display = Frame(mainframe)
result = Label(display, text='display result')
mainframe.grid() # within root
login.grid(row=0, column=0) # within mainframe
label.grid(row=0, column=0) # within login
entry.grid(row=0, column=1) # within login
display.grid() # within mainfram
result.grid(row=2, column=0) # within display

Multiple line text entry box in python

In python i have been making a text editor like Microsoft word but i don't know how to make a text entry box for the user to put input. Here is my code! (ps thank you!)
from tkinter import *
import sys
def doNothing():
print("Test")
root = Tk()
root.title("TextEditor")
root.geometry("300x200")
menu = Menu(root)
root.config(menu=menu)
subMenu = Menu(menu)
menu.add_cascade(label="File", menu=subMenu)
subMenu.add_command(label="New Project...", command =doNothing)
subMenu.add_command(label="Save", command=doNothing)
subMenu.add_separator()
editMenu = Menu(menu)
menu.add_cascade(label="Edit", menu=editMenu)
editMenu.add_command(label="Undo",command=doNothing)
root.mainloop()
You can do that like this:
TextArea = Text()
TextArea.pack(expand=YES, fill=BOTH)
If you want a scrollbar with it:
TextArea = Text()
ScrollBar = Scrollbar(root)
ScrollBar.config(command=TextArea.yview)
TextArea.config(yscrollcommand=ScrollBar.set)
ScrollBar.pack(side=RIGHT, fill=Y)
TextArea.pack(expand=YES, fill=BOTH)
Hope this helped, good luck!
It is an old question but currently following is a very good method for scrollable multiline text entry:
ScrolledText(mainwin, width=50, height=5).pack()
Full program:
from tkinter import *
from tkinter.scrolledtext import ScrolledText
mainwin = Tk()
ScrolledText(mainwin, width=50, height=5).pack()
mainwin.mainloop()
Following demo application shows its usage further and comparison with entry box (for python3):
from tkinter import *
from tkinter.scrolledtext import ScrolledText
mainwin = Tk()
Label(mainwin, text="An Entry Box:").grid(row=0, column=0)
ent = Entry(mainwin, width=70); ent.grid(row=0, column=1)
Button(mainwin, text="Print Entry", command=(lambda: print(ent.get()))).grid(row=0, column=2, sticky="EW")
Label(mainwin, text="ScrolledText Box:").grid(row=1, column=0)
st = ScrolledText(mainwin, height=5); st.grid(row=1, column=1)
Button(mainwin, text="Print Text", command=(lambda: print(st.get(1.0, END)))).grid(row=1, column=2, sticky="EW")
Button(mainwin, text="Exit", command=sys.exit).grid(row=2, column=0, columnspan=3, sticky="EW")
mainwin.mainloop()

Resources