user2126752
user2126752

Reputation: 59

Python Tkinter GUI scrambled

I'm trying to create a GUI for a simple numerical estimation of differential equation solution, but the layout doesn't work as intended (I've tried pack and grid). This is my first GUI and maybe I'm missing something simple. Thanks in advance.

Regards,

Piotr

from Tkinter import *
import matplotlib.pyplot as plt

class Application(Frame):
    def run_brussel(self):
        t_start = float(self.t_start_entry.get())
        t_end = float(self.t_end_entry.get())
        t_diff = float(self.t_diff_entry.get())
        k1 = float(self.k1_entry.get())
        k2 = float(self.k2_entry.get())
        k3 = float(self.k3_entry.get())
        k4 = float(self.k4_entry.get())
        A = float(self.A_entry.get())
        B = float(self.B_entry.get())
        X = float(self.X_entry.get())
        Y = float(self.Y_entry.get())
        mode = self.mode.get()

        brussel = brussel_func(t_start, t_end, t_diff, k1, k2, k3, k4, A, B, X, Y)
        plot_brussel(mode, brussel[0], brussel[1], brussel[2])

    def createWidgets(self):
        self.t_start_label = Label(text="start time")
        self.t_start_label.grid(row=0, column=0, sticky=W)
        self.t_start_entry = Entry(self)
        self.t_start_entry.delete(0, END)
        self.t_start_entry.insert(0, "0.0")
        self.t_start_entry.grid(row=0, column=1)

        self.t_end_label = Label(text="end time")
        self.t_end_label.grid(row=1, column=0, sticky=W)
        self.t_end_entry = Entry(self)
        self.t_end_entry.delete(0, END)
        self.t_end_entry.insert(0, "100.0")
        self.t_end_entry.grid(row=1, column=1)

        self.t_diff_label = Label(text="time precision")
        self.t_diff_label.grid(row=2, column=0, sticky=W)
        self.t_diff_entry = Entry(self)
        self.t_diff_entry.delete(0, END)
        self.t_diff_entry.insert(0, "0.0001")
        self.t_diff_entry.grid(row=2, column=1)

        self.k1_label = Label(text="k1 value")
        self.k1_label.grid(row=3, column=0, sticky=W)
        self.k1_entry = Entry(self)
        self.k1_entry.delete(0, END)
        self.k1_entry.insert(0, "1.0")
        self.k1_entry.grid(row=3, column=1)

        self.k2_label = Label(text="k2 value")
        self.k2_label.grid(row=4, column=0, sticky=W)
        self.k2_entry = Entry(self)
        self.k2_entry.delete(0, END)
        self.k2_entry.insert(0, "1.0")
        self.k2_entry.grid(row=4, column=1)

        self.k3_label = Label(text="k3 value")
        self.k3_label.grid(row=5, column=0, sticky=W)
        self.k3_entry = Entry(self)
        self.k3_entry.delete(0, END)
        self.k3_entry.insert(0, "1.0")
        self.k3_entry.grid(row=5, column=1)

        self.k4_label = Label(text="k4 value")
        self.k4_label.grid(row=6, column=0, sticky=W)
        self.k4_entry = Entry(self)
        self.k4_entry.delete(0, END)
        self.k4_entry.insert(0, "1.0")
        self.k4_entry.grid(row=6, column=1)

        self.A_label = Label(text="initial A concentr.")
        self.A_label.grid(row=7, column=0, sticky=W)
        self.A_entry = Entry(self)
        self.A_entry.delete(0, END)
        self.A_entry.insert(0, "1.0")
        self.A_entry.grid(row=7, column=1)

        self.B_label = Label(text="initial B concentr.")
        self.B_label.grid(row=8, column=0, sticky=W)
        self.B_entry = Entry(self)
        self.B_entry.delete(0, END)
        self.B_entry.insert(0, "2.5")
        self.B_entry.grid(row=8, column=1)

        self.X_label = Label(text="initial X concentr.")
        self.X_label.grid(row=9, column=0, sticky=W)
        self.X_entry = Entry(self)
        self.X_entry.delete(0, END)
        self.X_entry.insert(0, "0.0")
        self.X_entry.grid(row=9, column=1)

        self.Y_label = Label(text="initial Y concentr.")
        self.Y_label.grid(row=10, column=0, sticky=W)
        self.Y_entry = Entry(self)
        self.Y_entry.delete(0, END)
        self.Y_entry.insert(0, "0.0")
        self.Y_entry.grid(row=10, column=1)

        self.mode = IntVar()
        self.modus_operandi_label = Label(text="plot type")
        self.modus_operandi_label.grid(row=0, column=2, sticky=W)
        self.modus_operandi_button = Radiobutton(self, text="X : Y", variable=self.mode, value=True).grid(row=1, column=2, sticky=W)
        self.modus_operandi_button = Radiobutton(self, text="X, Y : time", variable=self.mode, value=False).grid(row=2, column=2, sticky=W)

        self.plot = Button(self)
        self.plot["text"] = "PLOT",
        self.plot["command"] = self.run_brussel
        self.plot.grid(row=1, column=3)

        self.QUIT = Button(self)
        self.QUIT["text"] = "QUIT"
        self.QUIT["fg"]   = "red"
        self.QUIT["command"] =  self.quit
        self.QUIT.grid(row=0, column=3)

    def __init__(self, master=None):
        Frame.__init__(self, master)
        self.grid()
        self.createWidgets()

def brussel_func(t_start, t_end, t_diff, k1, k2, k3, k4, A, B, X, Y):
    t = t_start
    t_list = []
    t_list.append(0)
    X_list = [X]
    Y_list = [Y]
    step = 0

    while t < t_end:
        X_diff = t_diff * (k1 * A - k2 * B * X_list[step] + k3 * X_list[step]**2 *             Y_list[step] - k4 * X_list[step])
        Y_diff = t_diff * (k2 * B * X_list[step] - k3 * X_list[step]**2 * Y_list[step])
        X_list.append(X)
        Y_list.append(Y)
        t_list.append(t)
        t += t_diff
        X += X_diff
        Y += Y_diff
        step += 1

    return [t_list, X_list, Y_list]

def plot_brussel(mode, t_list, X_list, Y_list):
    p = []

    #plots X : Y    
    if mode == True:
            p = plt.plot(X_list, Y_list)
            plt.xlabel('x')
            plt.ylabel('y')

    #plots X, Y : time
    else:
            p = plt.plot(t_list, X_list, label="X")
            p += plt.plot(t_list, Y_list, label="Y")
            plt.legend(loc="upper left", bbox_to_anchor=(1,1))
            plt.xlabel('time')

    #displays chosen plot
    plt.show(p)

def main():
    root = Tk()
    root.wm_title("Brusselator")
    app = Application(master=root)
    app.mainloop()
    root.destroy()

if __name__ == '__main__':
    main()  

Upvotes: 0

Views: 252

Answers (1)

Brionius
Brionius

Reputation: 14118

The problem is that you forgot to give your Labels a root widget. Honestly I'm surprised they showed up at all - I think they must have defaulted to the active Tk instance, so they got gridded outside the frame.

Anyhow, the fix is easy - add self as the first argument of all your Labels.

I.e. wherever you wrote something like this:

self.t_start_label = Label(text="start time")

instead write this:

self.t_start_label = Label(self, text="start time")
                           ^^^^

The Labels then appear next to the Entries.

One style note - I recommend that you move all your Widget.grid calls to one place in your code - makes it much easier to read, understand, and change the grid layout.

Upvotes: 1

Related Questions