SQL Result als Command angeben

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
Kampfgummibaerlie
User
Beiträge: 27
Registriert: Freitag 18. Juni 2021, 14:44

Code: Alles auswählen

def cleaning():
    textfield.config(state="normal")
    textfield.delete("1.0", END)
    textfield.config(state="disabled")

def das_kaffee():
    cleaning()
    print("Hi!")

conn.pgcursor.execute("select name, lower(command) from links where rechte <= 1")
checklinks = conn.pgcursor.fetchall()

for roa in checklinks:
    comment = roa[1],
    menubar.add_command(
        label=roa[0],
        command = comment
        )
und ich würde eben gerne den lower(command), den ich aus der SQL Query gewinne, als Funktionsnamen als Command angeben.

spiele schon eine Weile damit herum, komme aber nicht auf einen Zweig :(

Danke im Voraus!
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Alles, was Funktionen brauchen, muß über ihre Argumente kommen. textfield kommt in `cleaning` aus dem nichts.
Benutze keine Abkürzungen, was bedeutet roa?
Hast Du jetzt einen Kommentar oder ein Kommando?
Der Code hinterläßt mehr Fragen als dass er hilft, Dein Problem zu verstehen.

Was möchtest Du erreichen? Zeige ein Beispiel, das wirklich hilft. Ich vermute, dass dazu die SQL-Abfrage gar nicht nötig ist.
rogerb
User
Beiträge: 878
Registriert: Dienstag 26. November 2019, 23:24

@Kampfgummibaerlie, es wäre wirklich mehr Information nötig. Ich vermute mal du möchtest Menu-Punkte in Abhängigkeit der Daten aus der Datenbank anlegen.
Wenn das so ist, wäre es sehr ungewöhnlich, eigentlich falsch. Der Menu-Bar in jedem GUI sollte eigentlich sehr statisch sein. Allein schon wegen der Benutzbarkeit eines solchen GUIs ist es besser, wenn der Benutzer immer wieder mit einem vertrauten Menu präsentiert wird.
Falls sich die Menu-Daten aber sowieso nie ändern, gehören sie auch gar nicht in die Datenbank.

Trotzdem mal zu deinem Problem:
Aus der Datenbank bekommst du die Commands wahrscheinlich als String. Die Methode menubar.add_command() erwartet aber für das "command" Argument eine Funktion und keinen String.
Dazu brauchst du Mapping(Dictionary)
Wenn aus der Datenbank also ein Command "send_data" kommt, dann sollte es auch eine Funktion mit dem Namen send_data geben.

Code: Alles auswählen

def send_data():
    # code for sending data
    pass


command_mapping = {
    "send_data": send_data
}

# command_label und command_method kommen als String aus der Datenbank
menubar.add_command(
    label=command_label
    command = command_mapping[command_method]
)
Aber wie gesagt, eigentlich finde ich das Vorgehen grundsätzlich fraglich.
Kampfgummibaerlie
User
Beiträge: 27
Registriert: Freitag 18. Juni 2021, 14:44

Das ich zur Hintergrundgeschichte komme:

Ich habe eine stehende Datenbank sowie eine Homepage für das Kaffee meiner Mutter, und um ehrlich zu sein, schreibe ich an dem Ganzen aus Langeweile, und wenn ich auf dem Weg etwas lernen darf, wieso nicht?

roa ist eine Abwandlung von "row" für mich, weil ich meistens mehrere Rows (zB auf der Homepage) nutze, und da bin ich einfach nach dem Schema vorgegangen (rowa wäre mir zu lange => dadurch roa...)
ich habe angefangen mit Datenbanken, vl. habe ich von dem her auch eine gewisse Sympathie gegenüber diesen.

ich arbeite auch mit Benutzern, und so weiter.

Unter Umständen nette Info:
Das ganze ist derzeit nicht live, wird es wohl auch nie gehen, aber ich freue mich, dass ich dadurch dazulernen kann.

Für weitere private Fragen (bei Interesse) bitte PN
Sirius3
User
Beiträge: 18250
Registriert: Sonntag 21. Oktober 2012, 17:20

Was ist denn an `rowa` zu lange? Zumal das `a` in rowa auch nicht sehr aussagekräftig ist. Code wird öfter gelesen, als geschrieben, und da hilft ein gesparter getippter Buchstabe nichts.

Die ganze Hintergrundgeschichte ist zwar ganz nett, aber erklärt noch nicht, was Du eigentlich damit erreichen willst.
Benutzeravatar
__blackjack__
User
Beiträge: 13999
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

``conn.pgcursor`` sieht auch verdächtig komisch aus. Was ist denn `conn` hier und wie kommt da `pgcursor` drauf? Datenbankcursor haben in aller Regel eine kurze Lebensdauer, so dass man die nicht wirklich sinnvoll an die Verbindung heften kann. Und falls die Verbindung hier aus einem Fremdmodul kommt, pappt man da nicht einfach selber irgendwelche Attribute dran.

Das ``roa[1],`` ist ein Tupel mit einem Element. Ich denke Du willst da als `command` eher kein Tupel übergeben, denn Tupel sind nicht aufrufbar, machen als `command` also gar keinen Sinn.

Der Code sollte also eher so aussehen (ungetestet, mit `closing()` aus dem `contextlib`-Modul):

Code: Alles auswählen

    ...
    
    with closing(connection.cursor()) as cursor:
        cursor.execute(
            "SELECT name, lower(command) FROM links WHERE rechte <= 1"
        )
        menu_rows = cursor.fetchall()

    for item_name, command_name in menu_rows:
        menubar.add_command(
            label=item_name, command=NAME_TO_COMMAND[command_name]
        )
Da ist dann auch nicht das unsägliche `roa` sondern gleich sinnvolle Namen für die beiden Elemente.

Problem ist hier noch, dass die Funktion wahrscheinlich noch irgendwelche Argumente brauchen wird, denn wenn da am Ende `cleaning` aufgerufen wird, dann muss da ja irgendwie `textfeld` hin übergeben werden, wie Sirius3 angemerkt hat.

Und das geht bei GUI-Programmen über objektorientierte Programmierung (OOP). Da kommt man nicht wirklich drum herum wenn man eine nicht total triviale GUI programmiert.
“The best book on programming for the layman is »Alice in Wonderland«; but that's because it's the best book on anything for the layman.” — Alan J. Perlis
Antworten