Auf den richtigen Button aus Array zugreifen.

Fragen zu Tkinter.
Antworten
tchaluppa
User
Beiträge: 7
Registriert: Mittwoch 2. August 2023, 10:55

Hallo liebe Gemeinde,

ich bin neu hier und habe direkt mal eine Frage als Anfänger.
Seit kurzer Zeit mach ich mich mit Python vertraut.

Mein Problem ist, dass ich nicht auf den passenden Button zugreifen kann.

Code: Alles auswählen

#!/usr/bin/env python3

import tkinter as tk

root = tk.Tk()

fieldlist = list()
buttonlist = ("1", "2", "3", "4", "5", "6", "7", "8", "9")

def game_move(name):
	print(name)
	btn.config(text="X")

def create_buttons(btnname):
	global btn
	btn = tk.Button(root, name=btnname, height="10", width="15", command=lambda: game_move(btnname))
	fieldlist.append(btn)

for buttons in buttonlist:
	create_buttons(buttons)

rowcount = 0
columncount = 0
maxcolumns = 3

for button in fieldlist:
	button.grid(row=rowcount, column=columncount)

	columncount += 1
	if maxcolumns == columncount:
		columncount = 0
		rowcount +=1

root.mainloop()
In der Funktion game_move(name) erhalte ich zwar den richtigen Namen des Buttons.
Wenn ich versuche den Text des geklickten Buttons zu ändern, wird nur der letzte (neunte) Button mit den Text versehen, nicht der geklickte.
Ich gehe davon aus, dass es der letzte im Schleifendurchlauf ist. Aber warum erhalte ich dann den passenden Namen des geklickten Buttons?

Vielen Dank schon mal im Voraus
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@tchaluppa: Der Name kommt als Argument beim Aufruf rein und als Button benutzt Du das globale `btn` an das halt nur *ein* Button zu jedem Zeitpunkt gebunden sein kann. Wie sollte das denn auch etwas anderes als der zuletzt diesem Namen zugewiesene sein‽

Sonstige Anmerkungen: Eingerückt wird mit vier Leerzeichen, nicht mit Tabs.

Grunddatentypen haben in Namen nichts zu suchen. Noch weniger wenn etwas `*list` heisst, dann aber ein Tupel ist. Wobei das eine Liste sein sollte, denn die Elemente da drin haben ja alle die gleiche Bedeutung.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.

Funktionen und Methoden bekommen alles was sie ausser Konstanten benötigen, als Argument(e) übergeben. Vergiss das es ``global`` überhaupt gibt. Wenn man sich Zustand über Aufrufe hinweg merken muss, schreibt man dafür eine Klasse.

`buttonlist` enthält keine Buttons, sollte also nicht so heissen. `buttons` enthält auch keine Buttons und auch nicht irgendetwas anderes in der Mehrzahl, das ist auch falsch benannt. Genau so erzeugt `create_buttons()` keine Buttons, sondern nur *einen* Button. Die Funktion macht eigentlich auch nicht wirklich genug, und das sie etwas an eine Liste anhängt die eigentlich übergeben werden müsste, ist auch unschön.

Namen sollten keine kryptischen Abkürzungen enthalten oder gar nur daraus bestehen. Der Name soll dem Leser vermitteln was der Wert dahinter im Programm bedeutet, nicht zum rätseln zwingen. Wenn man `button` meint, sollte man nicht nur `btn` schreiben.

Zwischenstand (ungetestet):

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk
from functools import partial

COLUMN_COUNT = 3


def do_game_move(button, name):
    print(name)
    button["text"] = "X"


def main():
    root = tk.Tk()

    buttons = []
    for text in map(str, range(1, 10)):
        button = tk.Button(root, height=10, width=15)
        button["command"] = partial(do_game_move, button, text)
        buttons.append(button)

    for i, button in enumerate(buttons):
        row_index, column_index = divmod(i, COLUMN_COUNT)
        button.grid(row=row_index, column=column_index)

    root.mainloop()


if __name__ == "__main__":
    main()
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
tchaluppa
User
Beiträge: 7
Registriert: Mittwoch 2. August 2023, 10:55

Hallo __blackjack__

Dein Beispiel macht genau das, was es soll. Vielen Dank dafür erstmal.
Zum Thema Aufbau vom Code hab ich wohl zu viele Youtube-Videos für Anfänger geschaut.
Da wird das in 95% der Fälle so gemacht.
Das "Einrücken" hatte ich so verstanden, dass man es nicht mischen darf.
Stehe wie gesagt noch komplett am Anfang. Vielen Dank daher für das Aufzeigen der Fehler.

Jetzt kann ich mich noch gut umgewöhnen. ;)
Benutzeravatar
Cybernuschel
User
Beiträge: 4
Registriert: Donnerstag 12. Mai 2022, 13:39

Sonstige Anmerkungen: Eingerückt wird mit vier Leerzeichen, nicht mit Tabs.

Hallo liebe Python-Experten,

meine Einsteigerfrage lautet:
Warum soll zum einrücken kein Tabulator benutzt werden. Ich weiß, dass es im PEP 8 steht, aber der Sinn ist mir nicht klar.
Ich benutze Visual Studio Code zum programmieren. Um einen neuen Block mit vielen Zeilen einzurücken, markiere ich alle Zeilen des zu erstellenden Blockes und drücke dann "Tab". Alles ist perfekt. Sollte ich den Block fälschlicherweise zu tief eingerückt haben, nutze ich "Shift + Tab" und schon ist es korrigiert. So wird es auch oft in Dokumentationen beschrieben.
mir ist nicht ganz klar, wie ich einen größeren Block der aus vielen Zeilen besteht, mit jeweils 4 Leerzeichen komfortabel einrücken soll.

Vielleicht könnt ihr mir helfen.

Gruß Frank
Benutzeravatar
sparrow
User
Beiträge: 4195
Registriert: Freitag 17. April 2009, 10:28

Hallo Cybernuschel,

Du verwechselst die Taste Tab mit dem Zeichen Tab ( \t ). Wenn du deinen mit VSC geschriebenen Code anschaust, wirst du feststellen, dass der Editor mit hoher Wahrscheinlichkeit Leerzeichen statt des Tab-Zeichens ( \t ) verwendet.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Es gibt einen Unterschied, zwischen der TAB-Taste und dem Tab-Zeichen. Der Editor sollte so eingestellt sein, dass beim Drücken der Tab-Taste automatisch vier Leerzeichen eingefügt werden.
Benutzeravatar
Cybernuschel
User
Beiträge: 4
Registriert: Donnerstag 12. Mai 2022, 13:39

Ach das war das alles eine Verwechslung. Ich habe an die TAB-Taste gedacht und nicht an Tab ( \t ).

Vielen Dank für die schnellen Antworten. Echt super!

Gruß Cybernuschel
Antworten