2013-08-15 2 views
0

Я пытаюсь создать графический интерфейс для простой численной оценки решения дифференциальных уравнений, но макет не работает должным образом (я пробовал пакет и сетку). Это мой первый графический интерфейс, и, возможно, я пропустил что-то простое. Заранее спасибо.Python Tkinter GUI scrambled

С уважением,

Петр

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

И что именно вы намерены? Вы не указываете номера строк или столбцов на вызовы 'grid', поэтому я не уверен, что вы ожидаете от этого. Кроме того, я не могу сказать, что делает ваш код, потому что он имеет ошибки отступа (см. Строку сразу после строки 'while t

+0

Исправлена ​​ошибка с отступом (уже поздно, и я использую табуляцию, а не пробелы - пришлось ее вручную менять). В опубликованной версии нет информации о строках и столбцах (я ее тестировал). Я использовал первый столбец для меток ввода, второй столбец для записей, третий столбец для ярлыка для радиообмена и радиокнопки и четвертый столбец для кнопок «quit» и «plot». Python отображает его в следующем порядке: записи, радиокнопки, кнопки, метки. Это явно неверно. – user2126752

+0

Итак, правильный способ указать расположение ваших виджетов заключается в атрибутах 'row' и' column' метода 'grid', так почему бы вам не опубликовать код, где вы это делаете, и мы можем вам помочь отлаживать оттуда? – Brionius

ответ

1

Проблема заключается в том, что вы забыли дать этикетки корневой виджет. Честно говоря, я удивлен, что они вообще появились - я думаю, что они должны были дефолтироваться с активным экземпляром Tk, поэтому они получили сетку за рамкой.

Во всяком случае, исправление очень просто - добавьте self в качестве первого аргумента всех ваших ярлыков.

I.e. где бы вы ни писали что-то вроде этого:

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

вместо этого написать:

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

Этикетки затем появляются рядом с записей.

Одна заметка в стиле - я рекомендую вам переместить все ваши звонки Widget.grid в одно место в коде - это значительно упрощает чтение, понимание и изменение схемы сетки.

+0

Привет, спасибо. Не могли бы вы взглянуть на последнюю проблему с этим скриптом? Кажется, что matplotlib не освобождает память должным образом: http://stackoverflow.com/questions/18256233/python-matplotlib-memory-clog-not-clearing – user2126752

+0

@ user2126752 Конечно, я посмотрю. Если этот ответ решит вашу проблему, отметьте его как «принятый», щелкнув маленькую галочку, чтобы будущие пользователи знали, что она сработала для вас, и этот сайт становится более полезным. – Brionius