Tkinter: Как получить доступ к виджетам в методе init из других методов - PullRequest
0 голосов
/ 09 июня 2019

Я создаю графический интерфейс Python для генерации справочной таблицы. Для этого мне нужно, чтобы пользователь выбрал бесплатные и фиксированные параметры. Я сделал это с помощью флажков. Когда пользователь устанавливает флажок, этот параметр считается свободным параметром. Затем пользователь должен указать начальную точку, конечную точку и шаг шага в этом параметре. Есть 15 таких параметров. Они могут быть исправлены или свободны.

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

Однако записи создаются в методе init. А минимумы, максимумы и приращения создаются с помощью отдельных функций. Проблема в том, как мне получить доступ к каждой конкретной записи, чтобы иметь возможность отключить их при вызове метода активации () этого флажка?

Я также хочу получить значения записей min, max и inc для каждого свободного параметра и иметь возможность проверить количество свободных параметров.

Вот код:

class GenerateLUT(tk.Frame):
    cnt = 0
    alltextFields = ["N","Cab","Car","Cw","Cm","Cbrown", "rsoil0","LIDFa","LIDFb","TypeLIDF","LAI","hspot","tts","tto","psi" ]
    def __init__(self,parent,controller):
        tk.Frame.__init__(self,parent,width=1000, height=600)
        self.controller = controller


        imgBack = tk.PhotoImage(file='7.gif')
        lblBackGround = tk.Label(self, image=imgBack,width=700, height=600)
        lblBackGround.image = imgBack
        lblBackGround.place(relwidth=1, relheight=1)

        vcmd = (self.register(self.validate), '%P', '%S','%W')

        self.lbl_choose=tk.Label(self,text="Choose free parameters:");self.lbl_choose.grid(row=1,column=7,padx=4,pady=4);self.lbl_choose.config(font=("Georgia", 17))
        self.lbl_min = tk.Label(self,text="Min");self.lbl_min.grid(row=2,column=8,padx=4,pady=4);self.lbl_min.config(font=("Georgia", 17))
        self.lbl_max = tk.Label(self,text="Max");self.lbl_max.grid(row=2,column=9,padx=4,pady=4);self.lbl_max.config(font=("Georgia", 17))
        self.lbl_inc = tk.Label(self,text="Inc");self.lbl_inc.grid(row=2,column=10,padx=4,pady=4);self.lbl_inc.config(font=("Georgia", 17))

        self.lbl_N = tk.Label(self,text="Structure Coefficient(N)",anchor="w",width=40,bg='white'); self.lbl_N.grid(row=3,column=4,padx=4,pady=4);
        self.txt_N = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_N.grid(row=3,column=7,padx=4,pady=4);   

        self.lbl_Cab = tk.Label(self,text="Chlorophyll Content(Cab) (µg.cm-2)",anchor="w",width=40); self.lbl_Cab.grid(row=4,column=4,padx=4,pady=4);
        self.txt_Cab = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_Cab.grid(row=4,column=7,padx=4,pady=4);        

        self.lbl_Car = tk.Label(self,text="Carotenoid content(Car) (µg.cm-2)",anchor="w",width=40); self.lbl_Car.grid(row=5,column=4,padx=4,pady=4);
        self.txt_Car = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_Car.grid(row=5,column=7,padx=4,pady=4);    

        self.lbl_Cbrown = tk.Label(self,text="Brown pigment content(Cbrown)(arbitrary units)",anchor="w",width=40); self.lbl_Cbrown.grid(row=6,column=4,padx=4,pady=4);self.lbl_Cbrown.config(font=("Candara", 15))
        self.txt_Cbrown = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_Cbrown.grid(row=6,column=7,padx=4,pady=4);

        self.lbl_Cw = tk.Label(self,text="Equivalent Water Thickness(Cw) (cm)",anchor="w",width=40); self.lbl_Cw.grid(row=7,column=4,padx=4,pady=4);
        self.txt_Cw = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_Cw.grid(row=7,column=7,padx=4,pady=4);

        self.lbl_Cm = tk.Label(self,text="Leaf mass per area(Cm) (g.cm-2)",anchor="w",width=40); self.lbl_Cm.grid(row=8,column=4,padx=4,pady=4);
        self.txt_Cm = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_Cm.grid(row=8,column=7,padx=4,pady=4);

        self.lbl_LIDFa = tk.Label(self,text="Average leaf slope(LIDFa)",anchor="w",width=40); self.lbl_LIDFa.grid(row=9,column=4,padx=4,pady=4);
        self.txt_LIDFa = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_LIDFa.grid(row=9,column=7,padx=4,pady=4);

        self.lbl_LIDFb = tk.Label(self,text="Distribution bimodality(LIDFb)",anchor="w",width=40); self.lbl_LIDFb.grid(row=10,column=4,padx=4,pady=4);
        self.txt_LIDFb = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_LIDFb.grid(row=10,column=7,padx=4,pady=4);  

        self.lbl_TypeLIDF = tk.Label(self,text="Type of leaf angle distribution(TypeLIDF)",anchor="w",width=40); self.lbl_TypeLIDF.grid(row=11,column=4,padx=4,pady=4);self.lbl_Cm.config(font=("Candara", 15))
        self.txt_TypeLIDF = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_TypeLIDF.grid(row=11,column=7,padx=4,pady=4);

        self.lbl_LAI = tk.Label(self,text="Leaf Area Index(LAI) (m^2/m^2)",anchor="w",width=40); self.lbl_LAI.grid(row=12,column=4,padx=4,pady=4);self.lbl_Cm.config(font=("Candara", 15))
        self.txt_LAI = tk.Entry(self,width=10); self.txt_LAI.grid(row=12,column=7,padx=4,pady=4);

        self.lbl_hspot = tk.Label(self,text="Hot Spot(hspot)",anchor="w",width=40); self.lbl_hspot.grid(row=13,column=4,padx=4,pady=4);self.lbl_Cm.config(font=("Candara", 15))
        self.txt_hspot = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_hspot.grid(row=13,column=7,padx=4,pady=4);

        self.lbl_tts = tk.Label(self,text="Solar Zenith Angle(tts) (°)",anchor="w",width=40); self.lbl_tts.grid(row=14,column=4,padx=4,pady=4);
        self.txt_tts = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_tts.grid(row=14,column=7,padx=4,pady=4)

        self.lbl_tto = tk.Label(self,text="Observer Zenith Angle(tto) (°)",anchor="w",width=40); self.lbl_tto.grid(row=15,column=4,padx=4,pady=4);
        self.txt_tto = tk.Entry(self,width=10); self.txt_tto.grid(row=15,column=7,padx=4,pady=4)

        self.lbl_psi = tk.Label(self,text="Azimuth(psi) (°)",anchor="w",width=40); self.lbl_psi.grid(row=16,column=4,padx=4,pady=4);
        self.txt_psi = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_psi.grid(row=16,column=7,padx=4,pady=4)

        self.lbl_rsoil0 = tk.Label(self,text="rsoil0",anchor="w",width=40); self.lbl_rsoil0.grid(row=17,column=4,padx=4,pady=4);
        self.txt_rsoil0 = tk.Entry(self,width=10,validate = 'key', validatecommand = vcmd); self.txt_rsoil0.grid(row=17,column=7,padx=4,pady=4)

        self.btn_getLUT = tk.Button(self,text="Generate Look-Up-Table",command=lambda:self.getLUT())
        self.btn_getLUT.grid(row=19,column=7);self.btn_getLUT.config(font=("Georgia", 15))
        self.btn_home = tk.Button(self,text="HOME PAGE",command=lambda:controller.show_frame("StartPage"),font='Verdana',fg='red')
        self.btn_home.grid(row=1,column=2)

        def to_float(txt):

            """ Safely convert any string to a float.  Invalid strings return 0.0 """ 
            try:
                return float(txt)
            except ValueError: 
                return 0.0

        def row_n(parent, n, init_show = 0 ):
            eval("self.txt_N.config(state='disabled')")
            """ Create one row of the display. """
            # tk.Variables
            v_show = tk.IntVar()
            v_min = tk.StringVar()
            v_max = tk.StringVar()
            v_incr = tk.StringVar()
            v_message = tk.StringVar()
            v_show.set(init_show)
            v_message.set("OK")

            def do_trace(*args):
                """ Runs every time any of the three Entries change value. 
                    Sets the message to the appropriate text.
                """
                lo = to_float(v_min.get())
                hi = to_float(v_max.get())
                inc = to_float(v_incr.get())
                if lo < hi and inc <=hi:
                    v_message.set('OK')
                else:
                    txt = ''
                    if lo >= hi: 
                        txt += 'Min >= Max'
                        messagebox.showinfo("Input Error", "Minimum should not be greater than maximum")
                    if inc > hi:
                        if len(txt): txt += ' & '
                        txt += 'Incr > Max'
                        messagebox.showinfo("Input Error", "Increment should not be greater than maximum")
                    v_message.set(txt)

            # Set trace callback for changes to the three StringVars
            v_min.trace('w', do_trace)
            v_max.trace('w', do_trace)
            v_incr.trace('w', do_trace)

            def activation(*args):
                alltextFields = ["N","Cab","Car","Cw","Cm","Cbrown", "rsoil0","LIDFa","LIDFb","TypeLIDF","LAI","hspot","tts","tto","psi" ]
                """ Runs when the tickbox changes state """
                row_str = 3;col_str=8;
                if v_show.get():
                    e_min.grid(row = n, column = 8)
                    e_max.grid(row = n, column = 9)
                    e_inc.grid(row = n, column = 10)
##                    eval("self.txt_" + alltextFields[n-3] + ".config(state='disabled')") # access the entry here
                    message.grid(row = n, column = 11)
                else:
                    e_min.grid_remove()
                    e_max.grid_remove()
                    e_inc.grid_remove()
##                    eval("self.txt_" + alltextFields[n-2] + ".config(state='normal')") # access the entry here
                    message.grid_remove()

            tk.Checkbutton(parent, 
                text = ' '.format(n), 
                variable = v_show, command = activation ).grid(row = n, column = 6)
            e_min = tk.Entry(parent, width=5, textvariable = v_min, validate = 'key', validatecommand=vcmd)
            e_min.config(font=('Candara', 15))
            e_max =tk.Entry(parent, width=5, textvariable = v_max,validate = 'key', validatecommand=vcmd)
            e_max.config(font=('Candara', 15))
            e_inc = tk.Entry(parent, width=5, textvariable = v_incr,validate = 'key', validatecommand=vcmd)
            e_inc.config(font=('Candara', 15))
            message = tk.Label(parent, width=-15, textvariable = v_message)
            message.config(font=('Candara', 15))
            activation()

            return { 'Min': v_min, 'Max': v_max, 'Inc': v_incr }

        self.rows = []
        for r in range(3,18):
            self.rows.append(row_n(self, r, init_show=r%3 == 0 ))

        allWidgets  = ["N","Cab","Car","Cbrown","Cw","Cm","LIDFa","LIDFb", "TypeLIDF","LAI","hspot","tts","tto","psi","rsoil0"]
        for wid in allWidgets:
            widlbl = "self.lbl_" + wid + ".config(font=('Candara', 15))";

            eval(widlbl)

            widtxt = "self.txt_" + wid + ".config(font=('Candara', 15))";
            eval(widtxt)
##            if v_show.get():
##               eval("self.txt_" + alltextFields[n-3] + ".config(state='disabled')")


Я получаю ошибку:

Traceback (most recent call last):
  File "C:\PROSAIL_5B_Fortran\PROSAIL_5B_FORTRAN\PROSAIL_val.py", line 620, in <module>
    app = PROSAIL()
  File "C:\PROSAIL_5B_Fortran\PROSAIL_5B_FORTRAN\PROSAIL_val.py", line 27, in __init__
    frame = F(parent=container, controller=self)
  File "C:\PROSAIL_5B_Fortran\PROSAIL_5B_FORTRAN\PROSAIL_val.py", line 378, in __init__
    self.rows.append(row_n(self, r, init_show=r%3 == 0 ))
  File "C:\PROSAIL_5B_Fortran\PROSAIL_5B_FORTRAN\PROSAIL_val.py", line 303, in row_n
    eval("self.txt_N.config(state='disabled')")
  File "<string>", line 1, in <module>
NameError: name 'self' is not defined
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...