Drop-Down Menu mit Ausgabe

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
c.schroeder
User
Beiträge: 11
Registriert: Montag 18. Oktober 2021, 15:22

Hallo,

ich würde gerne ein Drop-Down Menu erstellen, mit der Eigenschaft, dass man das ausgewählte Objekt "weiterverarbeiten" kann.
Das ist mein bisheriger Code:

Code: Alles auswählen

from tkinter import *

ws = Tk()
ws.geometry('400x300')

def selection(choice):
    choice = variable.get()
    print(choice)

countries = ['Bahamas','Canada', 'Cuba']

# setting variable for Integers
variable = StringVar()
variable.set("decide")

# creating widget
dropdown = OptionMenu(
    ws,
    variable,
    *countries,
    command=selection
)

# positioning widget
dropdown.pack(expand=True)


# infinite loop 
ws.mainloop()
Dabei ist das Problem, dass das ausgewählte Objekt zwar ausgegeben wird, aber ich verstehe nicht wie ich das Objekt beispielsweise in eine Variable speichern kann, die ich dann auch außerhalb der Funktion nutzen kann.
Dafür hatte ich überlegt, ob man die Variable "choice" mit return aus der Funktion rausholt. Oder eventuell eine globale Variable definiert.
Dabei wird jedoch ganz zu Beginn eine frühere Variable ausgegeben...

Code: Alles auswählen

from tkinter import *

ws = Tk()
ws.geometry('400x300')

def selection(choice):
    choice2 = variable.get()
    print(choice2)
    return (choice2)

countries = ['Bahamas','Canada', 'Cuba']

# setting variable for Integers
variable = StringVar()
variable.set("decide")

# creating widget
dropdown = OptionMenu(
    ws,
    variable,
    *countries,
    command=selection
)

# positioning widget
dropdown.pack(expand=True)

print(choice2)

# infinite loop 
ws.mainloop()
Aus einem mir unbekannten Grund, funktioniert dieses Programm nur, wenn die Variable "choice2" heißt. Mit "choice" wird ein Fehler angegeben!...

Ich hoffe, dass mir jemand meine Verwirrung nehmen kann...
Viele Grüße
__deets__
User
Beiträge: 14538
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es wurde dir ja schonmal nahegelegt (vielleicht sogar von mir, muesste ich nachschauen): GUI-Programmierung ohne Objektorientierung - das geht nicht wirklich. Und da kannst du natuerlich dann zB das letzte ausgewaehlte Element einfach in einem Attribut eines Objektes merken. Denn mit global arbeitet man nicht, und return-Werte koennen Ereignisbehandler nicht haben.

Und der "unbekannte Grund" ist ganz einfach: wenn du das Argument von selection auch choice nennst, dann ueberschattet das deine globale Variable choice.
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

*-Importe benutzt man nicht, globale Variablen erst recht nicht. Man benutzt keine kryptischen Abkürzungen; für was soll `ws` denn stehen?
Und so, wie Du das Dir vorstellst, funktionieren GUIs nicht. Die reagieren auf Ereignisse. Wenn der Nutzer noch keine Chance hatte, etwas einzugeben, dann kann ja auch nichts in choice2 stehen. Jede Reaktion auf die Nutzereingabe muß in Event-Handler passieren.
c.schroeder
User
Beiträge: 11
Registriert: Montag 18. Oktober 2021, 15:22

@__deets__ : ja, die objektorientierte Programmierung hattest du mir schonmal nahegelegt. Leider weiß ich nicht wirklich wie ich da rangehen soll... müsste ich dafür eine Klasse erstellen?

Ich habe noch ein anderes Beispielprogramm für ein Drop-Down Menu gefunden, das auch mit .get versucht das zuletzt ausgewählte Argument auszugeben. Das Programm gibt etwas aus, jedoch nicht den Wert aus dem Drop-Down Menu.
Was ich nicht verstehe ist, woher das Programm weiß welche Argumente (hier: Input_Value und Output_Value) mit in die Funktion "Check_Input" genommen werden sollen.

Code: Alles auswählen

# Button
Convert = Button(root, text="Convert", command=Check_Input)
Convert.grid(row=1, column=3)
Gesamtes Programm:

Code: Alles auswählen

from tkinter import *
from PIL import ImageTk, Image

# Dropdown menu options
Temp_Options = ["Celsius", "Fahrenheit", "Kelvin"]

root = Tk()
root.title("The World\'s Best Temperature Converter")
root.geometry("575x250")
root.eval('tk::PlaceWindow . center')


# Checks what units were input
def Check_Input():
    print (Input_Value.get)
    if Input_Value.get == "Celsius":
        print("Input Recieved = Celsius")
        Celsius()
    if Input_Value.get == "Fahrenheit":
        print("Input Recieved = Fahrenheit")
        Fahrenheit()
    if Input_Value.get == "Kelvin":
        Kelvin()
        print("Input Recieved = Kelvin")
    else:
        print("Check Input Failed")


# Convert FROM Celsius
def Celsius():
    Temp = User_Input.get()
    if Output_Value.get == "Celsius":
        Answer = ((Temp * 9/5) + 32)
    if Output_Value.get == "Fahrenheit":
        Answer = (Temp - 32 * (9/5))
    if Output_Value.get == "Kelvin":
        Answer = (Temp - 273.15)
    Final_Answer = Label(root, text=Answer)
    Final_Answer.grid(row=3, column=1)


# Convert FROM Fahrenheit
def Fahrenheit():
    Temp = User_Input.get()
    if Output_Value.get == "Celsius":
        Answer = ((Temp * 9/5) + 32)
    if Output_Value.get == "Fahrenheit":
        Answer = (Temp - 32 * (9/5))
    if Output_Value.get == "Kelvin":
        Answer = (Temp - 273.15)
    Final_Answer = Label(root, text=Answer)
    Final_Answer.grid(row=3, column=1)


# Convert FROM Kelvin
def Kelvin():
    Temp = User_Input.get()
    if Output_Value.get == "Celsius":
        Answer = ((Temp * 9/5) + 32)
    if Output_Value.get == "Fahrenheit":
        Answer = (Temp - 32 * (9/5))
    if Output_Value.get == "Kelvin":
        Answer = (Temp - 273.15)
    Final_Answer = Label(root, text=Answer)
    Final_Answer.grid(row=3, column=1)


# Choose Default for Input options
Input_Value = StringVar()
Input_Value.set("Select Input")

# Input Options Menu
Input_Menu = OptionMenu(
    root, Input_Value, *Temp_Options)
Input_Menu.config(width=9)
Input_Menu.grid(row=1, column=0)


# Chose Default for Output Options
Output_Value = StringVar()
Output_Value.set("Select Output")

# Output options menu
Output_Menu = OptionMenu(
    root, Output_Value, *Temp_Options)
Output_Menu.config(width=9)
Output_Menu.grid(row=1, column=2)


# Text Input Box
User_Input = Entry(root, width=50, borderwidth=10)
User_Input.grid(row=1, column=1)


# Button
Convert = Button(root, text="Convert", command=Check_Input)
Convert.grid(row=1, column=3)


root.mainloop()

Entschuldige die blöde Frage, aber ich stehe dabei auf dem Schlauch...
Sirius3
User
Beiträge: 17748
Registriert: Sonntag 21. Oktober 2012, 17:20

Toll, dass Du hier ein Programm postest, das Du irgendwo gefunden hast, aber nicht verstehst. Die Qualität des Programms ist auch eine 5-, wohlwollend, wenn man die offensichtlichen Bugs repariert.
Es fängt mit dem *-Import an, geht mit globalen Variablen weiter und endet an der fixen Fenstergröße. Dazu kommen Unmengen kopierter Code und katastrophal benannte Variabelnnamen.
Wenn Du schon aus vorhandenem Code was lernen willst, dann nimm wenigstens einigermaßen gute Vorlagen:

Code: Alles auswählen

import tkinter as tk
from functools import partial

TEMPERATURES = {
    "Celsius": (1, 0),
    "Fahrenheit": (5/9, 32 * 5/9),
    "Kelvin": (1, 273.15),
}


def convert(input_temperature_unit, output_temperature_unit, temperature_value, result):
    input_factors = TEMPERATURES[input_temperature_unit.get()]
    output_factors = TEMPERATURES[output_temperature_unit.get()]
    temperature = float(temperature_value.get())
    temperature_in_celsius = temperature * input_factors[0] - input_factors[1]
    answer = (temperature_in_celsius + output_factors[1]) / output_factors[0]
    result['text'] = f"{answer:.2f}"


def main():
    root = tk.Tk()
    root.title("The World's Best Temperature Converter")

    input_temperature_unit = tk.StringVar(root, "Select Input")
    output_temperature_unit = tk.StringVar(root, "Select Input")
    temperature_value = tk.StringVar(root)
    result = tk.Label(root)

    tk.OptionMenu(root, input_temperature_unit, *TEMPERATURES).pack()
    tk.Entry(root, width=50, borderwidth=10, textvariable=temperature_value).pack()
    tk.OptionMenu(root, output_temperature_unit, *TEMPERATURES).pack()
    tk.Button(root, text="Convert",
        command=partial(convert, input_temperature_unit, output_temperature_unit, temperature_value, result)
    ).pack()
    result.pack()

    root.mainloop()


if __name__ == "__main__":
    main()
c.schroeder
User
Beiträge: 11
Registriert: Montag 18. Oktober 2021, 15:22

@Sirius3 : Vielen Dank!
Antworten