Gebe ich gerne zu.
Deswegen versuche ich es zu verstehen
Projekterstellung mit GUI
Na dann - Quiz-Time!
Was ist der Unterschied zwischen einer Klasse und einer Instanz? Was ist eine Klassenvariable, und was eine Instanzvariable, und was ist der entscheidende Unterschied zwischen den beiden?
Wenn du
ausführst - woher kommt denn das self Argument, und wieso musstest du kein Argument übergeben? Und wieviele Argumente musst du beim Aufruf von pillepalle übergeben? Und warum?
Was ist der Unterschied zwischen einer Klasse und einer Instanz? Was ist eine Klassenvariable, und was eine Instanzvariable, und was ist der entscheidende Unterschied zwischen den beiden?
Wenn du
Code: Alles auswählen
class Foo:
def test(self):
print(“hallo”, self)
def pillepalle(self, argument):
print(argument)
f = Foo()
f.test()
Ich versuche es mal
Also ich muss pillepalle mit f.pillepalle("Test") aufrufen
weil Foo() die Klasse mit der Variable f instanziert ist.
Um in die Funktion von test zu kommen, muss ich diese einfach aufrufen, hier aber ohne self im print Modus um NUR das Wort Hallo zu bekommen.
Bei Pillepalle ist das anders, da hier ein Argument ( Variable) erwartet wird. Das muss ich einfach beim Aufruf dem OBJEKT?? mitgeben.
self bezieht sich dann hier auf Foo
AUch musste ich von den schrägen Anführungszeichen normale nehmen. Sonst ist das kein String, nehme ich an.
Also ich muss pillepalle mit f.pillepalle("Test") aufrufen
weil Foo() die Klasse mit der Variable f instanziert ist.
Um in die Funktion von test zu kommen, muss ich diese einfach aufrufen, hier aber ohne self im print Modus um NUR das Wort Hallo zu bekommen.
Bei Pillepalle ist das anders, da hier ein Argument ( Variable) erwartet wird. Das muss ich einfach beim Aufruf dem OBJEKT?? mitgeben.
self bezieht sich dann hier auf Foo
AUch musste ich von den schrägen Anführungszeichen normale nehmen. Sonst ist das kein String, nehme ich an.
Code: Alles auswählen
class Foo:
def test(self):
print("hallo")
def pillepalle(self, argument):
print(argument)
f = Foo()
f.test()
f.pillepalle("Test")
Die Anfuehrungszeichen haben nur was mit meinem iPad und dessen Vorstellung von "schoen" zu tun.
Was deine Antworten angeht: hmjaneesohalb.
Du hast die Frage nicht beantwortet, was eine Klasse von einer Instanz unterscheided. Und genau da machst du auch einen Fehler in "self bezieht sind dann hier auf Foo". Tut es nicht. Es bezieht sich auf eine INSTANZ von Foo. Und das ist kein Korinthenkacken. Das ist der entscheidende Unterschied.
Also: was unterscheided eine Klasse von einer Instanz dieser Klasse?
Was deine Antworten angeht: hmjaneesohalb.
Du hast die Frage nicht beantwortet, was eine Klasse von einer Instanz unterscheided. Und genau da machst du auch einen Fehler in "self bezieht sind dann hier auf Foo". Tut es nicht. Es bezieht sich auf eine INSTANZ von Foo. Und das ist kein Korinthenkacken. Das ist der entscheidende Unterschied.
Also: was unterscheided eine Klasse von einer Instanz dieser Klasse?
Ich möchte mal wieder den Respekt an alle aussprechen!
Ich les seit ca 1 Jahr hier mit und alle und auch alle anderen User sich hier die Zeit nehmen, das zu reflektieren und zu erläutern. Obwohl die Doku und Google manchmal auch helfen würde, bringt UNS Anfänger weiter!
Ich denke dieser Thread ist ein sehr gutes Beispiel für diese Kausalkette!
Ich les seit ca 1 Jahr hier mit und alle und auch alle anderen User sich hier die Zeit nehmen, das zu reflektieren und zu erläutern. Obwohl die Doku und Google manchmal auch helfen würde, bringt UNS Anfänger weiter!
Code: Alles auswählen
print(f"Danke an {username} für die Mühen!")
Eine Instanz wird zu einer Klasse innerhalb der Laufzeit erstellt.__deets__ hat geschrieben: ↑Freitag 29. März 2019, 13:20 Die Anfuehrungszeichen haben nur was mit meinem iPad und dessen Vorstellung von "schoen" zu tun.
Was deine Antworten angeht: hmjaneesohalb.
Du hast die Frage nicht beantwortet, was eine Klasse von einer Instanz unterscheided. Und genau da machst du auch einen Fehler in "self bezieht sind dann hier auf Foo". Tut es nicht. Es bezieht sich auf eine INSTANZ von Foo. Und das ist kein Korinthenkacken. Das ist der entscheidende Unterschied.
Also: was unterscheided eine Klasse von einer Instanz dieser Klasse?
Ich habe mal mit dem neueren Wissen, versucht die aufrufe anzupassen.
Dann aber in der Main()
über die Instanz app zur Klasse MainWindow.
Habe auch mal versucht was mir geraten worden ist, mit den Buttons umzusetzten. Das die Buttons immer alle da sein sollen, nur die aktuellen belgten, DISABLED setzten.
Läuft noch nicht ganz sooooo.
Button bzw. Entry Übergabe geht noch nicht.
Dann aber in der Main()
über die Instanz app zur Klasse MainWindow.
Habe auch mal versucht was mir geraten worden ist, mit den Buttons umzusetzten. Das die Buttons immer alle da sein sollen, nur die aktuellen belgten, DISABLED setzten.
Läuft noch nicht ganz sooooo.
Button bzw. Entry Übergabe geht noch nicht.
Code: Alles auswählen
import tkinter as tk
import sql_aufrufe
class MainWindow:
def __init__(self, master):
self.user_id_get_from_entry = tk.StringVar()
self.master = master
self.master.geometry("1500x1000")
self.master.title("Schießbuch")
self.frame1 = tk.Frame(self.master)
self.label1 = tk.Label(self.frame1, text = "Schießbuch", font = "Arial 16 bold")
self.label1.pack(padx=5, pady=30)
self.frame1.pack(side=tk.TOP)
def input_user_id(self):
frame =tk.Frame(self.master)
label = tk.Label(frame, text = "Bitte wähle deine ID aus: ")
label.pack(padx=5, pady=20)
entry_userid = tk.Entry(frame, textvariable = self.user_id_get_from_entry)
entry_userid.pack(padx=5, pady=20, side=tk.LEFT)
button_choice_userid = tk.Button(frame, text ="OK", command = self.get_user_id_from_button)
button_choice_userid.pack(padx=5, pady=20, side=tk.LEFT)
frame.pack(side=tk.TOP)
def get_user_id_from_button(self):
self.user_id_get_from_entry.set(entry_userid)
print(self.user_id_get_from_entry)
def buttons_places(self, db, range_id):
frame = tk.Frame(self.master)
occupied_places = sql_aufrufe.get_occupied_place_numbers(db, range_id)
max_places= sql_aufrufe.get_max_place_number(db, range_id)
label = tk.Label(frame, text = "Bitte tippe auf den Platz auf dem du schießt: ")
label.pack(padx=5, pady=5)
buttons = []
for i in range(1, max_places+1):
b = tk.Button(frame, height=5, width=5, text = i) #,command=lambda i=i: onClick(i))
b.pack(padx=5, pady=5, side=tk.LEFT)
for z in occupied_places:
b.config(state=tk.DISABLED)
else:
b.config(state=tk.NORMAL)
buttons.append(b)
frame.pack(side=tk.BOTTOM)
def show_users(self, db):
frame =tk.Frame(self.master)
users = sql_aufrufe.get_users(db)
for row in users:
user_label = tk.Label(frame, text= (row["ID"], row["UName"], row["UVorname"]),
fg = "red",
font = "Arial")
user_label.pack(fill=tk.X, pady=10)
frame.pack(side=tk.TOP)
def main():
db = sql_aufrufe.connect()
root = tk.Tk()
app = MainWindow(root)
app.input_user_id()
app.show_users(db)
app.buttons_places(db, 2)
root.mainloop()
if __name__ == '__main__':
main()
Ich finde es gar nicht soooo schlecht bis hierher..
Code: Alles auswählen
import tkinter as tk
import sql_aufrufe
class MainWindow:
db = sql_aufrufe.connect()
user_id = ""
range_id = ""
place_id = ""
def __init__(self, master):
self.master = master
self.master.geometry("1500x1000")
self.master.title("Schießbuch")
self.frame1 = tk.Frame(self.master)
self.label1 = tk.Label(self.frame1, text = "Schießbuch", font = "Arial 16 bold")
self.label1.pack(padx=5, pady=30)
self.frame1.pack(side=tk.TOP)
def input_user_id(self):
frame =tk.Frame(self.master)
label = tk.Label(frame, text = "Bitte wähle deine ID aus: ", font = "Arial 12 bold")
label.pack(padx=5, pady=20)
self.entry_userid = tk.Entry(frame)
self.entry_userid.pack(padx=5, pady=20, side=tk.LEFT)
self.entry_userid.focus()
button_choice_userid = tk.Button(frame, text ="OK", command = self.get_user_id_from_button)
button_choice_userid.pack(padx=5, pady=20, side=tk.LEFT)
frame.pack(side=tk.TOP)
def input_range_id(self):
frame =tk.Frame(self.master)
label = tk.Label(frame, text = "Bitte wähle den Stand aus: ", font = "Arial 12 bold")
label.pack(padx=5, pady=20)
self.entry_rangeid = tk.Entry(frame)
self.entry_rangeid.pack(padx=5, pady=5, side=tk.LEFT)
self.entry_rangeid.focus()
button_choice_userid = tk.Button(frame, text ="OK", command = self.get_range_id_from_button)
button_choice_userid.pack(padx=5, pady=5, side=tk.LEFT)
frame.pack(side=tk.TOP)
def get_range_id_from_button(self):
self.range_id = self.entry_rangeid.get()
self.buttons_places(self.db, self.range_id)
def get_user_id_from_button(self):
self.user_id = self.entry_userid.get()
self.show_range(self.db)
self.input_range_id()
def buttons_places(self, db, range_id):
frame = tk.Frame(self.master)
occupied_places = sql_aufrufe.get_occupied_place_numbers(db, range_id)
max_places= sql_aufrufe.get_max_place_number(db, range_id)
label = tk.Label(frame, text = "Bitte tippe auf den Platz auf dem du schießt: ", font= "Arial 12 bold")
label.pack(padx=5, pady=5)
buttons = []
for i in range(1, max_places+1):
b = tk.Button(frame, text = i) #,command=lambda i=i: onClick(i))
b.pack(padx=5, pady=5, side=tk.LEFT)
for z in occupied_places:
b.config(state=tk.DISABLED)
else:
b.config(state=tk.NORMAL)
buttons.append(b)
frame.pack(side=tk.BOTTOM)
def show_users(self, db):
frame =tk.Frame(self.master)
users = sql_aufrufe.get_users(db)
for row in users:
user_label = tk.Label(frame, text= (row["ID"], row["UName"], row["UVorname"]),
fg = "red",
font = "Arial")
user_label.pack(fill=tk.X, pady=10)
frame.pack(side=tk.TOP)
def show_range(self, db):
frame =tk.Frame(self.master)
range_str = sql_aufrufe.get_range(db)
for row in range_str:
range_label = tk.Label(frame, text= (row["ID"], row["StandLang"]),
fg = "red",
font = "Arial")
range_label.pack(fill=tk.X, pady=10)
frame.pack(side=tk.TOP)
def main():
db = sql_aufrufe.connect()
root = tk.Tk()
app = MainWindow(root)
app.show_users(db)
app.input_user_id()
root.mainloop()
if __name__ == '__main__':
main()
Einrückung ist uneinheitlich und es gibt zu viele Leerzeilen, als dass man das lesen möchte. Alle Deine Klassenattribute sind kein und sollten in __init__ definiert werden.
Dass man da nach und nach Felder angezeigt bekommt, aber auch noch die vorherigen Felder benutzen kann ist seltsam.
In buttons_places ist eine for-Schleife in der immer das selbe gemacht wird und die einen else-Block hat, der immer ausgeführt wird und das was im for-Block gemacht wird, wieder überschreibt, ziemlich unsinnig.
Wenn `db` an `self` gebunden ist, ist es unnötig, das auch noch als Parameter an Methoden zu übergeben.
Alle Attribute, die in einer Instanz verwendet werden, sollten schon in __init__ angelegt werden, auch wenn erstmal mit dem Wert None.
Komisch ist auch, dass es zwei Datenbankverbindungen gibt.
Dass man da nach und nach Felder angezeigt bekommt, aber auch noch die vorherigen Felder benutzen kann ist seltsam.
In buttons_places ist eine for-Schleife in der immer das selbe gemacht wird und die einen else-Block hat, der immer ausgeführt wird und das was im for-Block gemacht wird, wieder überschreibt, ziemlich unsinnig.
Wenn `db` an `self` gebunden ist, ist es unnötig, das auch noch als Parameter an Methoden zu übergeben.
Alle Attribute, die in einer Instanz verwendet werden, sollten schon in __init__ angelegt werden, auch wenn erstmal mit dem Wert None.
Komisch ist auch, dass es zwei Datenbankverbindungen gibt.
Hallo,
danke für deie Antwort.
Habe tatsächlich in der zwischen Zeit Aufrufe mittlerweile wieder in __init__ gepackt. Das db=connect ist auch nur noch in __init__
Mit der SChleife in der Schleife habe ich bissl rumgespielt. Möchte an und für sich nur die Buttons deren Zahl in occupied_places steht, deaktivieren.
Du meinst, die Klassenattribute user_id etc??? die sollen auch in __init__?
Die Rheinfolge bzw das nach und nach erscheinen, soll noch weg. macht ja so keinen Sinn.
Würde auch gern die ganze Sicht wechseln, nicht nur in so einer Folgeschaltung.
danke für deie Antwort.
Habe tatsächlich in der zwischen Zeit Aufrufe mittlerweile wieder in __init__ gepackt. Das db=connect ist auch nur noch in __init__
Mit der SChleife in der Schleife habe ich bissl rumgespielt. Möchte an und für sich nur die Buttons deren Zahl in occupied_places steht, deaktivieren.
Du meinst, die Klassenattribute user_id etc??? die sollen auch in __init__?
Die Rheinfolge bzw das nach und nach erscheinen, soll noch weg. macht ja so keinen Sinn.
Würde auch gern die ganze Sicht wechseln, nicht nur in so einer Folgeschaltung.
Code: Alles auswählen
user_id = ""
range_id = ""
place_id = ""
So der erste Brocken ist erstmal gemacht.
Komme über abfragen erstmal bis ans Insert und das klappt auch.
jetzt müssten noch die Prüfungen rein. Ob der User Standaufsicht ist... oder ob überhaupt jemand Standaufsicht ist.
Dann würde ich gern, wenn möglich bei der letzten Funktion, den ganzen kram wieder von vorne laufen lassen. Immer in einer Schleife.
Die Abfragen user und Stand, werden final ersetzt durch RFID und durch ein sysarg beim aufruf.
Selbstverständlich würde ich jetzt auch nach und nach, den Code verschlanken und vereinfachen wollen.
Komme über abfragen erstmal bis ans Insert und das klappt auch.
jetzt müssten noch die Prüfungen rein. Ob der User Standaufsicht ist... oder ob überhaupt jemand Standaufsicht ist.
Dann würde ich gern, wenn möglich bei der letzten Funktion, den ganzen kram wieder von vorne laufen lassen. Immer in einer Schleife.
Die Abfragen user und Stand, werden final ersetzt durch RFID und durch ein sysarg beim aufruf.
Selbstverständlich würde ich jetzt auch nach und nach, den Code verschlanken und vereinfachen wollen.
Code: Alles auswählen
import tkinter as tk
import sql_aufrufe
class MainWindow:
db = sql_aufrufe.connect()
def __init__(self, master):
user_id = ""
range_id = ""
place_id = ""
standaufsicht = "0"
caliber_id = ""
self.master = master
self.master.geometry("1350x500")
self.master.title("Schießbuch")
self.frame1 = tk.Frame(self.master)
self.label1 = tk.Label(self.frame1, text = "Schießbuch", font = "Arial 16 bold")
self.label1.pack(padx=5, pady=30)
self.frame1.pack(side=tk.TOP)
self.show_users()
self.input_user_id()
def input_user_id(self):
self.frame_user =tk.Frame(self.master)
label = tk.Label(self.frame_user, text = "Bitte wähle deine ID aus: ", font = "Arial 12 bold")
label.pack(padx=5, pady=20)
self.entry_userid = tk.Entry(self.frame_user)
self.entry_userid.pack(padx=5, pady=20, side=tk.LEFT)
self.entry_userid.focus()
self.button_choice_userid = tk.Button(self.frame_user, text ="OK", command = self.get_user_id_from_button)
self.button_choice_userid.pack(padx=5, pady=20, side=tk.LEFT)
self.frame_user.pack(side=tk.TOP)
def input_range_id(self):
self.frame_caliber =tk.Frame(self.master)
label = tk.Label(self.frame_caliber, text = "Bitte wähle den Stand aus: ", font = "Arial 12 bold")
label.pack(padx=5, pady=20)
self.entry_rangeid = tk.Entry(self.frame_caliber)
self.entry_rangeid.pack(padx=5, pady=5, side=tk.LEFT)
self.entry_rangeid.focus()
self.button_choice_rangeid = tk.Button(self.frame_caliber, text ="OK", command = self.get_range_id_from_button)
self.button_choice_rangeid.pack(padx=5, pady=5, side=tk.LEFT)
self.frame_caliber.pack(side=tk.TOP)
def input_show_caliber_buttons(self):
self.frame_show_caliber =tk.Frame(self.master)
caliber_str = sql_aufrufe.get_caliber(self.db, self.range_id)
buttons = []
for row in caliber_str:
caliber_button = tk.Button(self.frame_show_caliber, text = row["KaliberLang"] ,
height = 4, width = 20,
command=lambda caliber_value=row["ID"]: self.get_caliber_from_button(caliber_value))
caliber_button.pack(padx=3, pady=3, )
buttons.append(caliber_button)
self.frame_show_caliber.pack(side=tk.TOP)
def get_range_id_from_button(self):
self.frame_show_range.pack_forget()
self.frame_caliber.pack_forget()
self.range_id = self.entry_rangeid.get()
self.entry_rangeid.delete(0, 'end')
self.buttons_places()
def get_user_id_from_button(self):
self.frame_user.pack_forget()
self.frame_show_users.pack_forget()
self.user_id = self.entry_userid.get()
self.entry_userid.delete(0, 'end')
self.show_range(self.db)
self.input_range_id()
def get_place_from_button(self, place1_id):
self.frame_buttons_places.pack_forget()
self.place_id = place1_id
self.input_show_caliber_buttons()
def get_caliber_from_button(self, caliber1_id):
self.caliber_id = caliber1_id
sql_aufrufe.insert_rifleman(self.db, self.user_id, self.range_id, self.place_id, self.caliber_id, 0)
self.frame_show_caliber.pack_forget()
self.frame_show_users.pack()
self.frame_user.pack()
self.show_users()
def buttons_places(self):
self.frame_buttons_places = tk.Frame(self.master)
occupied_places = sql_aufrufe.get_occupied_place_numbers(self.db, self.range_id)
max_places= sql_aufrufe.get_max_place_number(self.db, self.range_id)
label = tk.Label(self.frame_buttons_places, text = "Bitte tippe auf den Platz auf dem du schießt: ", font= "Arial 12 bold")
label.pack(padx=10, pady=10)
buttons = []
for place in range(1, max_places+1):
button = tk.Button(self.frame_buttons_places, text = place ,
height = 4, width = 4,
command=lambda button_value=place: self.get_place_from_button(button_value))
if place in occupied_places:
button.config(state=tk.DISABLED)
button.pack(padx=3, pady=3, side=tk.LEFT)
buttons.append(button)
self.frame_buttons_places.pack(side=tk.TOP)
def show_users(self):
self.frame_show_users =tk.Frame(self.master)
users = sql_aufrufe.get_users(self.db)
for row in users:
user_label = tk.Label(self.frame_show_users, text= (row["ID"], row["UName"], row["UVorname"]),
fg = "red",
font = "Arial")
user_label.pack(fill=tk.X, pady=10)
self.frame_show_users.pack(side=tk.TOP)
def show_range(self, db):
self.frame_show_range =tk.Frame(self.master)
range_str = sql_aufrufe.get_range(db)
for row in range_str:
range_label = tk.Label(self.frame_show_range, text= (row["ID"], row["StandLang"]),
fg = "red",
font = "Arial")
range_label.pack(fill=tk.X, pady=10)
self.frame_show_range.pack(side=tk.TOP)
def main():
root = tk.Tk()
app = MainWindow(root)
root.mainloop()
if __name__ == '__main__':
main()
@matze1708: es ist irgendwie ermüdend, Dir jedes mal die selben Sachen zu sagen. `db` sollte kein Klassenargument sein und die lokalen Variablen in __init__ solltest Du statt dessen an self binden. Etwas das _id heißt sollte wohl eine Zahl sein und kein String.
Leerzeilen!!!!
und -zeichen.
`pack_forget` sollte `destroy` sein.
Leerzeilen!!!!
und -zeichen.
`pack_forget` sollte `destroy` sein.
Das wäre dann so?!
Code: Alles auswählen
class MainWindow:
def __init__(self, master):
self.db = sql_aufrufe.connect()
self.user_id = ""
self.range_id = ""
self.place_id = ""
self.standaufsicht = "0"
self.caliber_id = ""
self.username = ""
self.range_name = ""
self.master = master
self.master.geometry("1350x500")
self.master.title("Schießbuch")
self.frame1 = tk.Frame(self.master)
self.label1 = tk.Label(self.frame1, text = "Schießbuch", font = "Arial 16 bold")
self.label1.pack(padx=5, pady=30)
self.label_username = tk.Label(self.frame1, text = self.username, font = "Arial 14")
self.frame1.pack(side=tk.TOP)
self.show_users()
self.input_user_id()
Ich habe mal versucht nach besten Wissen und Gewissen, den Code zu sortieren und auch die Leerzeichen raus zubekommen.
Der Editor "Geany" scheint irgendwie nicht der Brüller zu sein.
Das destroy() wende ich offensichtlich falsch an.
Der Editor "Geany" scheint irgendwie nicht der Brüller zu sein.
Das destroy() wende ich offensichtlich falsch an.
Code: Alles auswählen
import tkinter as tk
import sql_aufrufe
class MainWindow:
def __init__(self, master):
self.db = sql_aufrufe.connect()
self.user_id = ""
self.range_id = ""
self.place_id = ""
self.standaufsicht = "0"
self.caliber_id = ""
self.username = ""
self.range_name = ""
self.master = master
self.master.geometry("1350x500")
self.master.title("Schießbuch")
self.frame1 = tk.Frame(self.master)
self.label1 = tk.Label(self.frame1, text = "Schießbuch", font = "Arial 16 bold")
self.label1.pack(padx=5, pady=30)
self.label_username = tk.Label(self.frame1, text = self.username, font = "Arial 14")
self.frame1.pack(side=tk.TOP)
self.show_users()
self.input_user_id()
def run_again(self):
self.user_id = ""
self.range_id = ""
self.place_id = ""
self.standaufsicht = "0"
self.caliber_id = ""
self.username = ""
self.range_name = ""
self.show_users()
self.input_user_id()
def show_users(self):
self.frame_show_users =tk.Frame(self.master)
users = sql_aufrufe.get_users(self.db)
for row in users:
user_label = tk.Label(self.frame_show_users, text= (row["ID"], row["UName"], row["UVorname"]),
fg = "red",
font = "Arial")
user_label.pack(fill=tk.X, pady=10)
self.frame_show_users.pack(side=tk.TOP)
def input_user_id(self):
self.frame_user =tk.Frame(self.master)
label = tk.Label(self.frame_user, text = "Bitte wähle deine ID aus: ", font = "Arial 12 bold")
label.pack(padx=5, pady=20)
self.entry_userid = tk.Entry(self.frame_user)
self.entry_userid.pack(padx=5, pady=20, side=tk.LEFT)
self.entry_userid.focus()
self.button_choice_userid = tk.Button(self.frame_user, text ="OK", command = self.get_user_id_from_button)
self.button_choice_userid.pack(padx=5, pady=20, side=tk.LEFT)
self.frame_user.pack(side=tk.TOP)
def get_user_id_from_button(self):
self.frame_user.destroy()
self.frame_show_users.destroy()
self.user_id = self.entry_userid.get()
self.entry_userid.delete(0, 'end')
self.show_logged_in_user()
self.show_range(self.db)
self.input_range_id()
def show_logged_in_user(self):
logged_in_user = sql_aufrufe.get_logged_in_user(self.db, self.user_id)
for row in logged_in_user:
self.username = row["UVorname"]
self.label_username.pack(padx=5, pady=30, side = tk.RIGHT)
def show_range(self, db):
self.frame_show_range =tk.Frame(self.master)
range_str = sql_aufrufe.get_range(db)
for row in range_str:
range_label = tk.Label(self.frame_show_range, text= (row["ID"], row["StandLang"]),
fg = "red",
font = "Arial")
range_label.pack(fill=tk.X, pady=10)
self.frame_show_range.pack(side=tk.TOP)
def input_range_id(self):
self.frame_caliber =tk.Frame(self.master)
label = tk.Label(self.frame_caliber, text = "Bitte wähle den Stand aus: ", font = "Arial 12 bold")
label.pack(padx=5, pady=20)
self.entry_rangeid = tk.Entry(self.frame_caliber)
self.entry_rangeid.pack(padx=5, pady=5, side=tk.LEFT)
self.entry_rangeid.focus()
self.button_choice_rangeid = tk.Button(self.frame_caliber, text ="OK", command = self.get_range_id_from_button)
self.button_choice_rangeid.pack(padx=5, pady=5, side=tk.LEFT)
self.frame_caliber.pack(side=tk.TOP)
def get_range_id_from_button(self):
self.frame_show_range.destroy()
self.frame_caliber.destroy()
self.range_id = self.entry_rangeid.get()
self.entry_rangeid.delete(0, 'end')
self.buttons_places()
def buttons_places(self):
self.frame_buttons_places = tk.Frame(self.master)
occupied_places = sql_aufrufe.get_occupied_place_numbers(self.db, self.range_id)
max_places= sql_aufrufe.get_max_place_number(self.db, self.range_id)
label = tk.Label(self.frame_buttons_places, text = "Bitte tippe auf den Platz auf dem du schießt: ", font= "Arial 12 bold")
label.pack(padx=10, pady=10)
buttons = []
for place in range(1, max_places+1):
button = tk.Button(self.frame_buttons_places, text = place ,
height = 4, width = 4,
command=lambda button_value=place: self.get_place_from_button(button_value))
if place in occupied_places:
button.config(state=tk.DISABLED)
button.pack(padx=3, pady=3, side=tk.LEFT)
buttons.append(button)
self.frame_buttons_places.pack(side=tk.TOP)
def get_place_from_button(self, place1_id):
self.frame_buttons_places.destroy()
self.place_id = place1_id
self.input_show_caliber_buttons()
def input_show_caliber_buttons(self):
self.frame_show_caliber =tk.Frame(self.master)
caliber_str = sql_aufrufe.get_caliber(self.db, self.range_id)
buttons = []
for row in caliber_str:
caliber_button = tk.Button(self.frame_show_caliber, text = row["KaliberLang"] ,
height = 4, width = 20,
command=lambda caliber_value=row["ID"]: self.get_caliber_from_button(caliber_value))
caliber_button.pack(padx=3, pady=3, )
buttons.append(caliber_button)
self.frame_show_caliber.pack(side=tk.TOP)
def get_caliber_from_button(self, caliber1_id):
self.caliber_id = caliber1_id
sql_aufrufe.insert_rifleman(self.db, self.user_id, self.range_id, self.place_id, self.caliber_id, 0)
self.frame_show_caliber.pack_forget()
self.run_again()
def main():
root = tk.Tk()
app = MainWindow(root)
root.mainloop()
if __name__ == '__main__':
main()
Wie muss den Code aussehen, das er getrennt von GUI und der Logik ist?
Muss ich dann die GUI in einer Klasse bauen und die Logik in der 2. Klasse? Dann muss das ja irgendwo zusammen kommen und Abläufe müssen ja wie in meinem Bsp. mit den Dynamischen Buttons auch irgendwo zusammen laufen.
Kann mir das gerade nicht so recht vorstellen, wie das auszusehen hat.
Muss ich dann die GUI in einer Klasse bauen und die Logik in der 2. Klasse? Dann muss das ja irgendwo zusammen kommen und Abläufe müssen ja wie in meinem Bsp. mit den Dynamischen Buttons auch irgendwo zusammen laufen.
Kann mir das gerade nicht so recht vorstellen, wie das auszusehen hat.
Tkinter ist dafuer nicht so super gut, weil die Kommunikation zwischen GUI und Logik bestenfalls ueber *Var-Objekte laeuft. Aber damit kann man zB sowas bauen:
Code: Alles auswählen
import time
import tkinter as tk
from functools import partial
class AppLogic:
def __init__(self):
self.time = tk.IntVar(0)
def periodic_callback(self):
"""
This must be invoked periodically
"""
# Just an example for something that literally
# changes over time
self.time.set(time.time())
class GuiApp:
def __init__(self, root, logic):
self._root = root
self._logic = logic
time = tk.Label(root, textvar=logic.time)
time.pack()
# start periodic callback
self._logic_timer_callback()
def _logic_timer_callback(self):
self._logic.periodic_callback()
self._root.after(500, self._logic_timer_callback)
def main():
root = tk.Tk()
logic = AppLogic()
app = GuiApp(root, logic)
root.mainloop()
if __name__ == '__main__':
main()
Noch ein Nachtrag: "bestenfalls ueber *Var-Objekte" ist natuerlich ein bisschen wenig.
Wenn das geht - wie zB in diesem Fall beim Label - ist das recht cool. Weil man so - bi-direktionial, also entweder aus der GUI Aenderungen bekommend, oder aus der Logik in die GUI - arbeitet.
Leider ist tkinter da aber nur mit sehr wenigen Moeglichkeiten versehen, *wo* man das alles einsetzen kann. Man wuerde sich eigentlich wuenschen, dass geht ueberall.
Stattdessen kann man Qt oder gar QML benutzen, und damit bekommt man das mit signal/slots, und besser noch qProperties hin.
Wenn das geht - wie zB in diesem Fall beim Label - ist das recht cool. Weil man so - bi-direktionial, also entweder aus der GUI Aenderungen bekommend, oder aus der Logik in die GUI - arbeitet.
Leider ist tkinter da aber nur mit sehr wenigen Moeglichkeiten versehen, *wo* man das alles einsetzen kann. Man wuerde sich eigentlich wuenschen, dass geht ueberall.
Stattdessen kann man Qt oder gar QML benutzen, und damit bekommt man das mit signal/slots, und besser noch qProperties hin.
Danke für dein Beispiel, werde es mir gleich mal ansehen.
Ich schätze der Haupttenor geht dahin, das ganze lieber mit QT umzubauen oder neu zubauen?
Ich glaube da muss ich dann einen neuen Thread aufmachen, sonst bekomme ich noch den "längster Thread" Award
Ich schätze der Haupttenor geht dahin, das ganze lieber mit QT umzubauen oder neu zubauen?
Ich glaube da muss ich dann einen neuen Thread aufmachen, sonst bekomme ich noch den "längster Thread" Award