Hilea Hilea - 29 days ago 7
Python Question

How to put a returned value of a function into a variable using python

hi this below is my python code. As i tried to express in the topic what i want is whenever the OK button is clicked from the pop up window i want it to be stored in the variable host, it is easy to print it but what i want is to put it inside my variable host, is there a way.

from tkinter import *
class dialog():
def __init__(self,master,question):
root=Toplevel(master)
root.geometry('200x84+20+15')
root.overrideredirect(True)
root.config(background='grey')
quetsion=question.capitalize()
Label(root,text=quetsion,bg='grey',fg='white',justify='center').grid(column=0,row=0,sticky=N+W,padx=50)
text=StringVar()
Entry(root,textvariable=text,bg='grey',fg='white',justify='center',width=30).grid(column=0,row=1,sticky=N+W,padx=8,pady=5)
Button(root,text='Ok',bg='grey',fg='white',width=11,justify='center',command=lambda:self.ok(text.get())).grid(column=0,row=2,sticky=N+W,padx=8,pady=5)
Button(root,text='Cancle',bg='grey',fg='white',width=11,justify='center',command=lambda:self.close(root)).grid(column=0,row=2,sticky=N+W,pady=5,padx=105)
def ok(self,value):#the OK function for the OK button
return value #the value to be put inside host when the OK button is clicked
def close(self,master):
master.destroy()

win=Tk()
win.geometry('0x0+0+0')
host=dialog(win,'What is your name')
print(host)
win.mainloop()


And also how does a tkinter simple dialogue do it? I tri3d to read the source code but it is not clear.

Answer Source

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()