There are several things you need to change for it to work properly.
First we need to fix some issues with the class.
You are going to need to use class attributes here and you need to assign at least the entry field and the label as a class attribute in order to be able to update the labels text. You will also need to set the grid()
location after you create the button or else when you try to use get()
on the entry field or try to update the label you will just get None
returned from the geometry manager.
You do not need string var here as you are using a button to call a method to update the text you can just use get()
on the entry field.
We can also reference master to a class attribute like this:
self.root = master
This will allow us to interact with the self.root attribute in any method without having to pass it as an argument.
So for your close()
method you can do self.root.destroy()
instead and it will work fine.
That being said you should make sure you create unique names that will not override what is already a method in python. For example close
is already used in python for closing an open file. So instead of naming your method close()
you should do something like close_app()
this will prevent any problems down the road if you start using pythons close method.
In a class you need to make sure that anything that needs to be called on more than once or in a method after the program has initialized that you have assigned it to a class attribute with self.
Now that we have cleaned up the class a bit lets fix your issue with updating host
and then printing it.
Because you can only have one tkinter application running at one time. You can create one window ( your dialog class ) to update a global variable ( your host
variable ) and then close itself out. Once dialog()
has closed the rest of the python program will run that comes after mainloop()
so We can write up some code to use the value of host
or even another tkinter app.
Take a look at the below code:
from tkinter import *
class dialog():
def __init__(self, master, question):
# removed Toplevel() because you code did not show a root window
# so top level is not needed here.
# If you would like this to be a Toplevel called from another class
# Then you can change self.root = master back to self.root = Toplevel(master)
self.root = master
self.root.geometry('200x84+20+15')
self.root.overrideredirect(True)
self.root.config(background='grey')
quetsion=question.capitalize()
self.lbl1 = Label(self.root, text=quetsion, bg='grey', fg='white', justify='center')
self.lbl1.grid(column=0,row=0,sticky=N+W,padx=50)
self.entry1 = Entry(self.root, bg='grey', fg='white', justify='center', width=30)
self.entry1.grid(column=0,row=1,sticky=N+W,padx=8,pady=5)
Button(self.root, text='Ok', bg='grey', fg='white', width=11, justify='center',
command=lambda:self.ok(self.entry1.get())).grid(column=0,row=2,sticky=N+W,padx=8,pady=5)
Button(self.root, text='Cancel', bg='grey', fg='white', width=11, justify='center',
command=lambda:self.close_app()).grid(column=0,row=2,sticky=N+W,pady=5,padx=105)
def ok(self, value):
global host
if self.entry1.get() != "":
host = self.entry1.get()
self.root.destroy()
def close_app(self):
self.root.destroy()
win=Tk()
win.geometry('0x0+0+0')
host = ""
dialog(win,'What is your name')
win.mainloop()
win = Tk()
Label(win, text="The host name is {}".format(host)).pack()
Button(win, text="Close", command = lambda: win.destroy()).pack()
win.mainloop()