click command and class

Fragen zu Tkinter.
Antworten
SkyEnd
User
Beiträge: 5
Registriert: Freitag 12. August 2022, 19:13

Hallo zusammen,

ich habe die Brackets für ein Turnier erstellt. Jetzt möchte ich mit einem Klick auf den Gewinner des jeweiligen Spiels das Event won() auslösen. Dabei soll der geklickte Spieler, in der Winner- und der andere in der Loser Paarung der nächsten Runde erscheinen.

Meine if Funktion in won funktioniert so leider nichts. Wie kann man das zum Click-Event ändern?
Und gibt es eine bessere Möglichkeit als die meine? (Ich muss jeder Player_Selection eine ID zuordnen und diese als global speichern)

Code: Alles auswählen

    class Player_Selection:
        def __init__(self,i,xc,yc):
            # player_var=tk.StringVar()
            self.name=tk.Button(root)
            self.name.config(bg = "#58595e", text =Player_List[i], activebackground = "#58595e", fg="#ff00ff", activeforeground="#00ff00", font=('arial', 10, "bold"), width=16, 
            command = won)
            self.name.place(x=xc, y=yc)
    
    def won():
        #I want it to creat Player_Selection when it's clicked
        global p1g1,p2g1
        if p1g1:
            p1g1=Player_Selection(0,243, 170)
            p2g1=Player_Selection(1,243, 280)

        elif p2g1:
            p1g1=Player_Selection(0,243, 170)
            p2g1=Player_Selection(1,243, 280)             
    
    def display_players():
        global p1g1
        if game_mode_var.get() == "2x4 DE Top4" or game_mode_var.get() == "4 DE":
            p1g1=Player_Selection(0,43, 140)
            p2g1=Player_Selection(1,43, 165)

            Player_Selection(2,43, 200)
            Player_Selection(3,43, 225)
Bild
Sirius3
User
Beiträge: 18051
Registriert: Sonntag 21. Oktober 2012, 17:20

Zu Deiner anderen Frage hat __blackjack__ schon sehr viel geschrieben, was hier auch gilt: keine globalen Variablen, keine kryptischen Abkürzungen bei Variablennamen.
Du benutzt Player_Selection als ob bei einem tk-Fenster frei gemalt werden könnte. Betrachte Fenster aber als etwas, das man einmal komplett aufbaut und dann nur noch die Eigenschaften verändert (also Text auf einem Label, ob ein Button aktiv ist oder nicht, etc).
Tk kennt zwei Modi, wie man Elemente auf einem Fenster platzieren kann: pack und grid. Durch geschickte Kombination mit Frames kann man damit auch komplexere Fenster erzeugen. Benutze niemals place.
Wenn ich es richtig sehe, dann willst du eine Art Turnierplan programmieren. Das erste worüber du dir Gedanken machen solltest, ist die richtige Datenstruktur, in der du die Spielerpaarungen speichern willst. Mit festen Variablen p1g1 und hard codierten Koordinaten wirst du relativ schnell an Grenzen stoßen.
Du scheinst auch verschiedene Turniermodi unterstützen zu wollen. Das verschiedene Verhalten aber direkt in die Methoden der einzelnen GUI-Komponenten einzubauen, ist aber nicht optimal, weil dadurch die eigentliche Logik, die hinter den verschiedenen Modi steckt, zwischen zwischen technischen Code für die GUI versteckt wird.
Ein nachhaltiger Ansatz ist es, wenn du die Turnierlogik komplett getrennt von der GUI entwickelst. Z.B eine Klasse Turnier, die eine Liste mit Spielern bekommt und von der Du Dich Startaufstellung abfragen kannst. Methoden, die den Ausgang einzelne Spiele übernehmen, um damit die Aufstellung für die nächste Runde berechnen zu können.
Der Vorteil ist dass du nun über Unit-Tests gründlich prüfen kannst, ob auch deine Turnierklasse richtig funktioniert. Verschiedene Modi können dann z.B als abgeleitete Klassen implementiert werden.
Wenn du damit fertig bist kannst du dich ganz auf die Darstellung in der GUI konzentrieren. Die Struktur in der Turnierklasse gibt dir dann auch schon eine Struktur für deine GUI vor, also wie viele Spalten und Zeilen gebraucht werden, welcher Text auf welchem Element stehen soll etc.
SkyEnd
User
Beiträge: 5
Registriert: Freitag 12. August 2022, 19:13

@Sirius3 danke für deine Antwort.


Ich stoße da einfach an meine Grenzen und weiß nicht, wie ich es anders machen kann ^^.
Sirius3 hat geschrieben: Montag 15. August 2022, 06:57 Zu Deiner anderen Frage hat __blackjack__ schon sehr viel geschrieben, was hier auch gilt: keine globalen Variablen, keine kryptischen Abkürzungen bei Variablennamen.
Also erst alle Fenster plazieren und dann mit config beschriften und den command ändern?
Du benutzt Player_Selection als ob bei einem tk-Fenster frei gemalt werden könnte. Betrachte Fenster aber als etwas, das man einmal komplett aufbaut und dann nur noch die Eigenschaften verändert (also Text auf einem Label, ob ein Button aktiv ist oder nicht, etc).
Ich möchte auf einem Bild, meine Brackets, die buttons draufpacken. Dabei müssen diese an fixen stellen platziert werden.
Ich fand place von den 3 Möglichkeiten am besten. Was ist denn da so schlecht daran?
Tk kennt zwei Modi, wie man Elemente auf einem Fenster platzieren kann: pack und grid. Durch geschickte Kombination mit Frames kann man damit auch komplexere Fenster erzeugen. Benutze niemals place.

Bin ich ja schon :lol:
Wenn ich es richtig sehe, dann willst du eine Art Turnierplan programmieren. Das erste worüber du dir Gedanken machen solltest, ist die richtige Datenstruktur, in der du die Spielerpaarungen speichern willst. Mit festen Variablen p1g1 und hard codierten Koordinaten wirst du relativ schnell an Grenzen stoßen.

Ich werde das Projekt erstmal auf Eis legen.
Das wichtigste, die Spielerliste einzulesen und zu mischen geht. Der Rest war nur eine Idee um etwas programmieren zu üben.
Aber ich denke, da sollte ich lieber die die Basics vertiefen.

Ps: Finde es eine super Idee erst den Hauptcode und dann die GUI zu schreiben
Benutzeravatar
__blackjack__
User
Beiträge: 13533
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@SkyEnd: Schlecht an absoluten Positionen und Grössen ist, dass das nicht funktioniert, weil diese Zahlen nicht zu dem Zoo von Bildschirmgrössen, -auflösungen, und -einstellungen passen, den es da draussen gibt. Ich sehe auch nicht, dass die an fixen Stellen platziert werden müssen. Die einzelnen Tage müssen nebeneinander. Die Paarungen sehen nicht so aus würde man die nicht in einem Grid abbilden könnte.

Code: Alles auswählen

- (void)countSheep {
    unsigned int sheep = 0;
    while ( ! [self isAsleep]) { ++sheep; }
}
SkyEnd
User
Beiträge: 5
Registriert: Freitag 12. August 2022, 19:13

@__blackjack__ naja die GUI Größe war als fixe gedacht, damit sie gleich der Größe des Hintergrundbildes ist. Aber stimmt auf anderen Bildschirmen kann man das dann vielleicht nicht verwenden.
Antworten