首页 > 解决方案 > 由于页面加载,tkinter 列表超出范围

问题描述

我有以下代码。我必须在页面(类)“FinanziatoriSemplici”中输入一些数据(它从我设置所有方法和内容的另一个文件继承另一个类“FinanziatoreSemplice”。输入数据用于填充对象“FinanziatoreSemplice”的列表,它是在控制器中定义为 self.FinanziatoriSemplici = []。使用“InizializzaFinanziatori”输入数据后,我使用“VerificaFinanziatori”方法检查化学。所以最后我计算了“FinanziatoreSemplice”类中定义的一些东西,并希望创建一个输出页面.它的原型是我尝试输出的类OutputPagetk.Label(self, text="energia condivisa da consumatore semplice: "+str(self.controller.Finanziatori_Semplici[0].CalcoloIncentivoEnergiaCondivisa)).pack()

但得到错误: tk.Label(self, text="energia condivisa da consumatore semplice: "+str(self.controller.Finanziatori_Semplici[0].CalcoloIncentivoEnergiaCondivisa)).pack() IndexError: list index out of range 我认为这是由于 SampleApp 类中的 for 。有没有办法解决这个问题,因为我没有想法......?

from tkinter import messagebox
from tkinter import Scrollbar, font as tkfont
from tkinter.constants import ANCHOR, BOTTOM, HORIZONTAL, X
from typing_extensions import IntVar  # python 3
from tkscrolledframe import ScrolledFrame

from Classi_Utenti import * 

class SampleApp(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        #Liste delle classi di utenti: sono accessibili globalmente per comodità
        self.Finanziatori_Semplici = []
        self.Consumatori_Semplici = []
        
        self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")

    #Creo scrollable: il container del container
        scrollable = ScrolledFrame(self, width=1250, height=300)
        scrollable.pack(side="top", fill="both", expand=True)
    
        #Collego l'azione di scrolling con la rotella e le frecce
        scrollable.bind_arrow_keys(self)
        scrollable.bind_scroll_wheel(self)

        #Creo il container dentro scrollable: come se creassi un container dentro ad un container
        container = scrollable.display_widget(tk.Frame) 
        
        #Istanzio lista dei frame
        self.frames = {}

        #Per aggiungere le pagine devo mettere il nome delle stesse nel ciclo for
        for F in (StartPage, FinanziatoriSemplici, OutputPage):
            page_name = F.__name__
            frame = F(parent=container, controller=self)
            self.frames[page_name] = frame

            #Metto le pagine nella stessa posizione, quella che è sul top viene mostrata
            frame.grid(row=0, column=0, sticky="nsew")
            
        self.show_frame("StartPage")
        
    def show_frame(self, page_name):
        '''Mostra frames per nome della pagine'''
        frame = self.frames[page_name]
        frame.tkraise()

class StartPage(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        label = tk.Label(self, text="Benvenuti nel framework di configurazione", font=controller.title_font)
        label.pack(side="top", fill="x", pady=10)
        button1 = tk.Button(self, text='Inizia la configurazione', command=lambda: controller.show_frame("FinanziatoriSemplici"))
        button1.pack()

################################################################################################################################
#PAGINA PER L'INIZIALIZZAZIONE DEI FINANZIATORI SEMPLICI
class FinanziatoriSemplici(tk.Frame, FinanziatoreSemplice):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        self.numero_utenti=tk.IntVar()

        self.labels_finanziatori = {
            'principale': [],
            'capitale_investito': [], 
            'tasso': [], 
            'tempo': []
            }

        self.entry_finanziatori = {
            'capitale_investito': [], 
            'tasso': [], 
            'tempo': []
            }

        tk.Label(self, text="Configurare I Finanziatori", font=controller.title_font).grid(row=0, column =0)
        tk.Label(self, text="Inserire il numero di utenti da configurare").grid(row=1, column = 0)
        self.entry_utenti = tk.Entry(self, text="Inserire numero Utenti", textvariable = self.numero_utenti)
        self.entry_utenti.grid(row=1, column=1)
        self.btn_utenti = tk.Button(self, text="OK", command= lambda: self.InizializzaFinanziatori(self.entry_utenti.get()))
        self.btn_utenti.grid(row=1, column=2)
        self.next = tk.Button(self, text="Prossimo passo", command = lambda: controller.show_frame("ConsumatoriSemplici") )
        self.next.grid(row=1, column=3)

    #Metodo per creare gli entry widgets & Labels
    def InizializzaFinanziatori(self, num):  
        #Variabili ausiliarie
        self.numero_utenti = 0
        self.numero_utenti = int(num)
        
        #self.capitale = []
        #self.cap = tk.IntVar()

        #Variabile per posizionare i vari elementi nelle righe
        k=2
        
        for i in range(0, self.numero_utenti):
            #MAIN label del finanziatore
            self.labels_finanziatori['principale'].append(tk.Label(self, text="Dati finanziatore numero "+str(i+1)))
            self.labels_finanziatori['principale'][i].grid(row=i*k+3, column = 0)
            #Bottone di validazione: notare lambda i=i
            validate = tk.Button(self, text="Valida Utente", command = lambda i=i:  self.ValidaFinanziatore(i))
            validate.grid(row=i*k+3, column = 1, pady=(0, 10), padx=(0,0))
            k = k+1

            #Label capitale investito
            self.labels_finanziatori['capitale_investito'].append(tk.Label(self, text="Dati sul capitale investito del finanziatore "+str(i+1)))
            self.labels_finanziatori['capitale_investito'][i].grid(row=i*k+4, column = 0, sticky= "W")
            #Entry widget capitale investito
            self.entry_finanziatori['capitale_investito'].append(tk.Entry(self, text = "Inserire il Capitale investito dal finanziatore "+str(i+1), textvariable= tk.IntVar()))
            #self.entry_finanziatori['capitale_investito'][i].insert(tk.END,0)
            self.entry_finanziatori['capitale_investito'][i].grid(row=i*k+4, column = 1)
            k= k+1

            #Label Tasso di interesse############################
            self.labels_finanziatori['tasso'].append(tk.Label(self, text="Dati sul tasso di interesse del finanziatore "+str(i+1)))
            self.labels_finanziatori['tasso'][i].grid(row=i*k+5, column = 0,sticky= "W")
            
            #Entry widget tasso
            self.entry_finanziatori['tasso'].append(tk.Entry(self, text = "Inserire il tasso per il finanziatore "+str(i+1), textvariable=tk.IntVar()))
            self.entry_finanziatori['tasso'][i].grid(row=i*k+5, column = 1)
            k= k+1
            
            ############################## N.B. L'ultima label ha pady
            #Label Tempo di ritorno 
            self.labels_finanziatori['tempo'].append(tk.Label(self, text="Inserire il tempo di ritorno per l'investimento per il finanziatore "+str(i+1), anchor='w'))
            self.labels_finanziatori['tempo'][i].grid(row=i*k+6, column = 0, pady=(0, 10), sticky= "W")
            #Entry widget tempo
            self.entry_finanziatori['tempo'].append(tk.Entry(self, text = "Inserire il tempo di ritorno per l'investimento "+str(i+1), textvariable = tk.IntVar()))
            self.entry_finanziatori['tempo'][i].grid(row=i*k+6, column = 1, pady=(0, 10))
            k= k+1

    #Metodo per validare l'input e caricare nella classe generale il finanziatore. Mi basta passare l'indice, per il resto accedo agli altri elementi tramite esso
    def ValidaFinanziatore(self, i):
            #print(self.entry_finanziatori['capitale_investito'][i].get()) Print di debug
            self.capitale = float(self.entry_finanziatori['capitale_investito'][i].get())
            self.tasso = float(self.entry_finanziatori['tasso'][i].get())/100
            self.tempo = float(self.entry_finanziatori['tempo'][i].get())

            #Controllo degli input
            if(self.tempo <= 0): 
                tk.messagebox.showerror("error", "Il tempo non può essere minore o pari a zero")
                return
            if(self.capitale <= 0): 
                tk.messagebox.showerror("error", "Il capitale investito non può essere minore o pari a zero")
                return
            if(self.tasso <= 0 or self.tasso > 100): 
                tk.messagebox.showerror("error", "Il tasso di interesse non può essere minore o pari a zero o maggiore di 100")
                return
            
            #Inizializzazione della classe
            #print("Finanziatore: "+str(i)+"\nCapitale: "+ str(self.capitale) + "\nTasso: " +str(self.tasso) + "\n Tempo: "+str(self.tempo)) Print di debug
            self.controller.Finanziatori_Semplici.append(FinanziatoreSemplice(self.capitale, self.tasso, self.tempo, i))
            #Print di debug
            print("\nMontante:" +str(self.controller.Finanziatori_Semplici[i].CalcoloMontante))

################ PROBLEM HERE: self.controller.Consumatori_Semplici[0].Montante list index out of range 
class OutputPage(tk.Frame, FinanziatoreSemplice): 
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        self.controller = controller
        tk.Label(self, text="energia condivisa da consumatore semplice: "+str(self.controller.Finanziatori_Semplici[0].CalcoloIncentivoEnergiaCondivisa)).pack()

if __name__ == "__main__":
    app = SampleApp()
    #Impostare la dimensione della pagina all'apertura
    #app.geometry("550x900")
    app.mainloop()

标签: pythontkinter

解决方案


推荐阅读