Reputation: 23
In tkinter, I am trying to print the text entry from text box to screen every time I click the button "click"
This is my code which is working fine
from tkinter import *
def get(s):
print(s.get())
win=Tk()
s=StringVar()
button=Button(win,text='click',command=lambda:get(s)).grid(row=1)
ent=Entry(win,textvariable=s).grid()
But when I do the same from new window, it is not working. This is the code that doesn't work
from tkinter import *
def get(s):
print(s.get())
def newwin():
win=Tk()
s=StringVar()
button=Button(win,text='click',command=lambda:get(s)).grid(row=1)
ent=Entry(win,textvariable=s).grid()
root=Tk()
but=Button(root,text='New',command=newwin).grid()
Everytime I click the 'click' button, I see a Blank line... But I want to see the output just like the previous case. Thanks in Advance !!
Upvotes: 0
Views: 1770
Reputation: 4964
Change
def newwin():
win=Tk()
...
to
def newwin():
win=Toplevel(root)
...
Edit (clarification):
Your code would also run if you change
def newwin():
win=Tk()
s=StringVar()
...
to
def newwin():
win=Tk()
s=StringVar(win)
...
but you shouldn't run multiple Tk() instances. See a good explanation here
Edit:
As for restricting selection of old window as asked by OP in a comment, I suggested to add a line to newwin()
:
def newwin():
win=Tk(Toplevel(root))
s=StringVar()
button=Button(win,text='click',command=lambda:get(s)).grid(row=1)
ent=Entry(win,textvariable=s).grid()
win.grab_set() # win will catch all events, until you close it
# so user cannot interact with root window widgets
# root.widthdraw() # alternative approach hides root window
# until Toplevel closes
root=Tk()
but=Button(root,text='New',command=newwin).grid()
Edit: (further enhancement with code rewrite. I think I already answered the OP question but the comments with additional questions can be confusing. Please try to ask a single question at a time in order for you to select the best answer for that question)
Now I just rewrote the thing to look like a more coehrent answer. Look that using grid
or pack
is not relevant here. I hope you find it educational. Notice the different imports. You can import differently, but this way you do not import all the tkinter
module names. ttk
widgets are just modern versions of the classic ones. I subclassed Toplevel
, assured parent __init__
is called and kept the new window related things together in that class. Note also the use of grab_set
and the event callback for when the child toplevel loses focus. This way root window never regains focus unless you close the child. So no window select. This is adapted from selected answer here
Note also that I do not keep any reference to the newly created window. If you need so, you have to adapt (maybe store the result of MyWinddow(root)
in a global var)
import tkinter as tk
from tkinter import Tk, ttk
class MyWindow(tk.Toplevel):
def __init__(self, parent, *kw):
super().__init__(parent, *kw)
self.title('New Toplevel Window')
self.myvar = tk.StringVar()
self.button = ttk.Button(self, text='Print myvar',
command=self.print_myvar)
self.entry = ttk.Entry(self, textvariable=self.myvar)
self.button.pack(pady=5)
self.entry.pack(padx=50, pady=5)
self.grab_set() # capture all the events
self.bind('<FocusOut>', self.dont_let_focus_go) # cannot focus root
def print_myvar(self):
print(self.myvar.get())
def dont_let_focus_go(self, event=None):
self.focus_force()
def new_window():
MyWindow(root)
root = Tk()
root.title('My Application Root Window')
button = ttk.Button(root, text='New Window', command=new_window)
button.pack(padx=50, pady=5)
root.mainloop()
Upvotes: 2