Modal forms with TKinter and Python

Python

I keep on learning (and sharing with you) Tkinter, and today I am going to write about modal forms, of course, customized to my needs (you can modify my code to suit your needs). In order to settle my knowledge, I have started from this code: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm. But I need some adjustments, in order to translate values from one form to another. A simple but tricky exercise.

Modal Forms

Every time you need a modal form is because you need new data to be use on another form, and that’s what I am explaing here. Let’s create a form, with a button and a label. When I click on the button, I will be asked for a new value using a modal form, that it will be write on the label.

First, let’s create the main form with a class named main, creating the button and the label. When clicking on the button, let’s transfer the value of the label. As you can see, and due to the characteristic of the variable, a StringVar, as you type the value change. If you need to validate the value, the solution is un broke the link when creating the Entry, and do the verification process on the ok function.

The full code is here:

from Tkinter import *

class main(Frame):
    def __init__(self, master):
        Frame.__init__(self, master=None)
        self.master.title("Probando Dialogos - Manejando datos")
        self.master.geometry("300x50")
        Button(root, text="cambiar valor", command=self.dialogo).pack()
        self.valor = StringVar()
        self.valor.set("Hola Manejando datos")
        Label(self.master, textvariable=self.valor).pack()

    def dialogo(self):
        d = MyDialog(root, self.valor, "Probando Dialogo", "Dame valor")
        root.wait_window(d.top)
        #self.valor.set(d.ejemplo)

class MyDialog:
    def __init__(self, parent, valor, title, labeltext = '' ):
        self.valor = valor

        self.top = Toplevel(parent)
        self.top.transient(parent)
        self.top.grab_set()
        if len(title) > 0: self.top.title(title)
        if len(labeltext) == 0: labeltext = 'Valor'
        Label(self.top, text=labeltext).pack()
        self.top.bind("<Return>", self.ok)
        self.e = Entry(self.top, text=valor.get())
        self.e.bind("<Return>", self.ok)
        self.e.bind("<Escape>", self.cancel)
        self.e.pack(padx=15)
        self.e.focus_set()
        b = Button(self.top, text="OK", command=self.ok)
        b.pack(pady=5)

    def ok(self, event=None):
        print "Has escrito ...", self.e.get()
        self.valor.set(self.e.get())
        self.top.destroy()

    def cancel(self, event=None):
        self.top.destroy()

root = Tk()
a = main(root)
root.mainloop()

The methos to be aware of are:

  • wait_window is the method that launch the new form
  • grab_set is the function that force the form to be modal, and you can’t work with the base form until the modal for is destroyed

 

Tkinter Formularios modales

Tkinter Formularios modales

 

I hope you use it in your projects! And have a nice day!