Projekterstellung mit GUI

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.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Gebe ich gerne zu.

Deswegen versuche ich es zu verstehen :-)
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

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

Code: Alles auswählen

class Foo:
     def test(self):
            print(“hallo”, self)
     def pillepalle(self, argument):
            print(argument)
f = Foo()
f.test()
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?
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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.

Code: Alles auswählen

class Foo:
     def test(self):
            print("hallo")
     def pillepalle(self, argument):
            print(argument)
f = Foo()
f.test()
f.pillepalle("Test")
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

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?
Tholo
User
Beiträge: 177
Registriert: Sonntag 7. Januar 2018, 20:36

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!

Code: Alles auswählen

print(f"Danke an {username} für die Mühen!")
Ich denke dieser Thread ist ein sehr gutes Beispiel für diese Kausalkette!
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

__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?
Eine Instanz wird zu einer Klasse innerhalb der Laufzeit erstellt.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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.

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()
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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()

Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

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.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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.
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

Code: Alles auswählen

    user_id = ""
    range_id = ""
    place_id = ""
    
gehoeren nicht dahin wo sie sind, denn KLASSEN-Attribute sind das falsche Mittel. Du willst INSTANZ-Attribute, und die definiert man in __init__.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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.

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()

Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@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.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

Das bekomme ich grad noch hin :-)

Aber Danke für deine unermüdliche Hilfe, trotz meines nicht gleichen Verständnisses.

Danke.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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()
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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.

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()
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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.
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

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()
__deets__
User
Beiträge: 14541
Registriert: Mittwoch 14. Oktober 2015, 14:29

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.
matze1708
User
Beiträge: 112
Registriert: Dienstag 12. März 2019, 11:49

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 :-)
Antworten