Franky
Franky

Reputation: 23

python - tkinter print from text box to screen

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

Answers (1)

progmatico
progmatico

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

Related Questions