Fehler beim Abfragen einer Variable aus einem Dropdown Menü

Fragen zu Tkinter.
Antworten
manhai
User
Beiträge: 2
Registriert: Sonntag 1. November 2020, 23:56

Hallo
Ich bin recht neu in der Python Programmierung deshalb schon mal Entschuldigung fals der Fehler offensichtlich ist.
Suche nach einer Antwort hat mich leider nicht weitergebracht, deshalb habe ich mich entschlossen hier nachzufragen.
Ich möchte im Grunde nur über die GUI einen Zahlenwert eingeben und eine Auswahl über ein Dropdown Menü machen. Beim klicken des Buttons möchte ich Datensätze über ein CSV Skript importieren und anschließend unter Einbeziehung der eingeben Daten, eine neue Liste generieren und diese mit CSV ausgeben.
Leider bekomme ich immer eine Fehlermeldung, wenn ich in der Funktion die Variable aus der GUI laden will.
Ich hoffe ihr könnt mir hier weiterhelfen.

Mfg
Manhai

Code: Alles auswählen

from tkinter import *
import csv
from random import *


def CSVImport(CSV_Name,Grade,Uncommon):
    Grade=str(Grade)
    Uncommon=str(Uncommon)
    Results = [["Name2", "Costs2", "Quelle2", "Uncommon2", "Grade2"]]  
    with open(CSV_Name) as csvdatei:
        csv_reader_object = csv.reader(csvdatei)
        for row in csv_reader_object:
            if row[4]==Grade and row[3]==Uncommon:          
                Results.append(row)    
    del Results[0]               
    return Results

def InitGUI(fenster):
    fenster = fenster
    fenster.title("Pathfinder Händler-Generator")
    Label_Name = Label(fenster, text="Pathfinder Händler-Generator", font=("Arial Bold", 30))
    Label_Warenwert = Label(fenster, text="Warenwert", font=("Arial Bold", 10))
    Label_MaxZauberGrad = Label(fenster, text="Maximaler Zaubergrad", font=("Arial Bold", 10))    
    MaxNomWarenwert= IntVar(fenster)
    spin_Warenwert = Spinbox(fenster, from_=100, to=1000000, width=5, textvariable=MaxNomWarenwert)
    Berechnen_button = Button(fenster, text="Berechnen", command=button_action)
    
    Label_Name.grid(column=0, row=1)
    Label_Warenwert.grid(column=0, row=4)
    spin_Warenwert.grid(column=1,row=4)
    Label_MaxZauberGrad.grid(column=0, row=7)
    #Aufbau der Array 0: Name der Gruppe:, 1: Kleinster Grad: 2: Prozentbis, 3: nächster Grad: 4: Prozentbis,       
    # 5: Kleinster Grad: 6: Prozentbis, 7: nächster Grad: 8: Prozentbis,
    ScrollMerchantRanks=[
            ['Mindere Schwache',0,15,1,95,2,100,2,100],
            ['Höhere Schwache',0,5,1,35,2,90,3,100],
            ['Mindere Durchschnittliche',2,10,3,55,4,100,4,100],
            ['Höhere Durchschnittliche',3,20,4,60,5,100,5,100],
            ['Mindere Mächtige',4,30,5,65,6,90,7,100],
            ['Höhere Mächtige',6,5,7,35,8,70,9,100]]    
    
    OptionList_MaxZauberGrad = [
    ScrollMerchantRanks[0][0],
    ScrollMerchantRanks[1][0],
    ScrollMerchantRanks[2][0],
    ScrollMerchantRanks[3][0],
    ScrollMerchantRanks[4][0],          
    ScrollMerchantRanks[5][0]] 
    
    variable_MaxZauberGrad = StringVar(fenster)
    variable_MaxZauberGrad.set(OptionList_MaxZauberGrad[0])
    opt_MaxZauberGrad = OptionMenu(fenster, variable_MaxZauberGrad, *OptionList_MaxZauberGrad)
    opt_MaxZauberGrad.config(width=20, font=('Arial Bold', 10))
    opt_MaxZauberGrad.grid(column=1,row=7)
    Berechnen_button.grid(column=0,row=9)

# der Benutzer den Button anklickt
def button_action():
    variable_MaxZauberGrad2 = str(variable_MaxZauberGrad.get())
    for i in range(0, 10):
        if (i==0):
            ScrollsArkan=[CSVImport('Scrolls_Arkan.csv',i,0)]
            ScrollsGod=[CSVImport('Scrolls_God.csv',i,0)]
        else:
            ScrollsArkan.append(CSVImport('Scrolls_Arkan.csv',i,0))
            ScrollsGod.append(CSVImport('Scrolls_God.csv',i,0))
        ScrollsArkan.append(CSVImport('Scrolls_Arkan.csv',i,1))
        ScrollsGod.append(CSVImport('Scrolls_God.csv',i,1))
    
    MerchantTrade = [["Name", "Costs", "Quelle", "Uncommon", "Grade"]]    
    #Kosten aus dem Schribt laden
    Costs=MaxNomWarenwert.get()
    #die Richtie Arary number bestimmen
    ArrayNumber=0
    while ArrayNumber <= 5:        
        if variable_MaxZauberGrad2 == ScrollMerchantRanks[ArrayNumber][0]:
            break
        ArrayNumber+=1;
      
    
    while Costs <= Costs: 
        #Der Zaubergrad wird besteimmt welcher für dne durchlauf gewürfelt wurde
        RandomGrade = randint(1, 100)
        x=1
        while x <= 4:
            if RandomGrade <= ScrollMerchantRanks[ArrayNumber][x+2]:
                Grade=ScrollMerchantRanks[ArrayNumber][x]
                break;
            x+=1
        
        RandomArt = randint(1, 100)
        if RandomArt <= 45: #Arkanhäufig
            Numer=Grade*2
            Spellnumber = randint(0, len(ScrollsArkan[Numer]))-1
            MerchantTrade.append(ScrollsArkan[Numer][Spellnumber])
        elif RandomArt <= 60: #Arkanselten
            Numer=Grade*2+1
            Spellnumber = randint(0, len(ScrollsArkan[Numer]))-1
            MerchantTrade.append(ScrollsArkan[Numer][Spellnumber])     
        elif RandomArt <= 90: #Göttlichhäufig
            Numer=Grade*2       
            Spellnumber = randint(0, len(ScrollsGod[Numer]))-1
            MerchantTrade.append(ScrollsGod[Numer][Spellnumber])        
        else: #Göttlichselten
            Numer=Grade*2+1 
            Spellnumber = randint(0, len(ScrollsGod[Numer]))-1
            MerchantTrade.append(ScrollsGod[Numer][Spellnumber])
    
        Costs+= int(MerchantTrade[-1][1])
             
    print(MerchantTrade)
    
    with open('employee_file2.csv', mode='w') as csv_file:
        fieldnames = ['Name', 'Costs', 'Quelle', 'Uncommon', 'Grade']
        writer = csv.DictWriter(csv_file, fieldnames=fieldnames)
        
        writer.writeheader()
        i=0
        maxl=int(len(MerchantTrade)-1)
        while i <= maxl: 
            writer.writerow({'Name': MerchantTrade[i][0], 'Costs': MerchantTrade[i][1], 'Quelle': MerchantTrade[i][2], 'Uncommon': MerchantTrade[i][3], 'Grade': MerchantTrade[i][4]})
            i+=1

  
fenster = Tk()
InitGUI(fenster) 
fenster.mainloop()
runfile('C:/Users/manhai/Documents/Phyton_Test/Pathfinder_Handler.py', wdir='C:/Users/manhai/Documents/Phyton_Test')
Exception in Tkinter callback
Traceback (most recent call last):
File "C:\Users\manhai\Anaconda3\lib\tkinter\__init__.py", line 1705, in __call__
return self.func(*args)
File "C:/Users/manhai/Documents/Phyton_Test/Pathfinder_Handler.py", line 59, in button_action
variable_MaxZauberGrad2 = str(variable_MaxZauberGrad.get())
NameError: name 'variable_MaxZauberGrad' is not defined
Sirius3
User
Beiträge: 18289
Registriert: Sonntag 21. Oktober 2012, 17:20

In button_action ist auch gar keine Variable variable_MaxZauberGrad definiert, sondern nur in InitGUI.
Alles was eine Funktion braucht, muß ihr über ihre Argumente mitgeben. Bei Callback-Funktionen wie button_action, die eigentlich keine Argumente haben, geht das mit functools.partial.

Generell werden in Python Variablennamen und Funktionen komplett klein geschrieben. Der Datentyp hat im Namen nichts verloren, erst recht nicht das Wort variable, denn dass es sich um eine Variable handelt, sollte klar sein.

Sternchenimporte sind schlecht, weil man sich damit unkontrolliert hunderte Namen in den eigenen Namensraum schaufelt. tkinter wird üblicherweise als "import tkinter as tk" importiert und alle Namen per tk.xyz angesprochen.

In `CSVImport` fängst Du mit einer Liste mit einem Element an, um dann zum Schluß dieses erste Element wieder rauszulöschen? Warum?
In Python ist alles ein Objekt, bei csv_reader_object bietet das Suffix _object keinen Mehrwert.
Bei csv-Dateien muß man bei open newline="" als Argument mit übergeben und am besten auch das richtige Encoding.

In InitGUI ist die Zeile fenster = fenster sinnlos. ScrollMerchantRanks sollte als Konstante KOMPLETT_GROSS geschrieben werden und am Anfang der py-Datei stehen. OptionList_MaxZauberGrad würde man mit einer for-Schleife oder Listcomprehension erzeugen, statt die Elemente explizit hinzuschreiben.
MaxNomWarenwert und variable_MaxZauberGrad müssen an button_action übergeben werden, per functools.partial.

In `button_action` sollte variable_MaxZauberGrad.get() schon einen String zurückliefern. Den nochmal mit str umzuwandeln ist überflüssig. Wenn man eine for-Schleife hat, wo der erste Durchgang anders behandelt wird, dann sollte der außerhalb der for-Schleife sein. Hier mußt Du aber nur die Listen als leere Listen vor der Schleife definieren.
Die while-Schleife ab Zeile 75 ist eigentlich eine for-Schleife und auch nicht über einen Index ArrayNumber, sondern über die Elemente von ScrollMerchantRanks direkt.
Spellnumber wird falsch berechnet. Das letzte Element wird doppelt so häufig gezogen, wie die anderen.
Die while-Schleife ab Zeile 120 sollte wieder eine for-Schleife sein.

Ab Zeile 125: die drei Zeilen sollten in einer Funktion main stehen, die zum Schluß per

Code: Alles auswählen

if __name__ == '__main__':
    main()
aufgerufen wird.
manhai
User
Beiträge: 2
Registriert: Sonntag 1. November 2020, 23:56

Leider bin ich früher nicht dazugekommen es auszuprobieren, aber nachdem ich den Code bereinigt habe und mir all eure Vorschläge zu herzen genommen habe hat es endlich geklappt.

Thx
Antworten