Hallo,
ich beginne gerade erst mit Python und sthe vermutlich z.Zt. 'auf dem Verständnis-Schlauch'.
Warum werden beim Clicken nicht die geklickten Buttons sondern immer der in der letzten Spalte rot?
Wäre für eine Klärung SUPER-dankbar.
from tkinter import *
class App:
def __init__(self, master):
frame=Frame(root)
frame.grid(row=0,column=0)
xmax = 3
ymax = 4
self.btn= [[0 for y in range(ymax)]]*3
for x in range(xmax):
for y in range(ymax):
self.btn[x][y] = Button(frame,command= lambda x1=x, y1=y: self.color_change(x1,y1), height=10, width=25)
self.btn[x][y].grid(column=x, row=y) #frame.pack()
def color_change(self,x,y):
self.btn[x][y].config(bg="red")
print(x,y)
root = Tk()
app = App(root)
root.mainloop()
Denkfehler bei ButtonArray
Sternchenimport sind böse, weil man sich da unkontrolliert hunderte Namen in den eigenen Namensraum schaufelt. Tkinter wird üblicherweise als `import tkinter as tk` eingebunden und alle Namen per tk.xy angesprochen.
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2 und mal 3 oder 5.
In Python erzeugt man keine Listen mit Dummy-Werten und füllt sie danach. `0` ist auch ein sehr schlechter Dummywert: None sagt, dass es (noch) kein Objekt gibt. Da liegt auch das Problem, dass Du keine Liste mit drei Unterlisten hast, sondern die Liste enthält drei mal (siehe *3), die selbe Liste, so dass nur die Buttons der letzten Reihe übrigbleiben, der Rest wird in der for-Schleife überschrieben (übrigens die innere Listcomprehension ist unötig, weil man bei unveränderlichen Objekten auch [0]*ymax schreiben könnte). Aber wie schon geschreiben: macht man nicht.
Statt `lambda` benutzt man `partial`. Keine Abkürzungen benutzen.
Die letzten drei Zeilen gehören auch in eine Funktion, die man üblicherweise `main` nennt. Das verhindert, dass man aus Versehen globale Variablen benutzt (wie in App.__init__).
Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal 2 und mal 3 oder 5.
In Python erzeugt man keine Listen mit Dummy-Werten und füllt sie danach. `0` ist auch ein sehr schlechter Dummywert: None sagt, dass es (noch) kein Objekt gibt. Da liegt auch das Problem, dass Du keine Liste mit drei Unterlisten hast, sondern die Liste enthält drei mal (siehe *3), die selbe Liste, so dass nur die Buttons der letzten Reihe übrigbleiben, der Rest wird in der for-Schleife überschrieben (übrigens die innere Listcomprehension ist unötig, weil man bei unveränderlichen Objekten auch [0]*ymax schreiben könnte). Aber wie schon geschreiben: macht man nicht.
Statt `lambda` benutzt man `partial`. Keine Abkürzungen benutzen.
Die letzten drei Zeilen gehören auch in eine Funktion, die man üblicherweise `main` nennt. Das verhindert, dass man aus Versehen globale Variablen benutzt (wie in App.__init__).
Code: Alles auswählen
import tkinter as tk
from functools import partial
class App:
COLUMN_MAX = 3
ROW_MAX = 4
def __init__(self, master):
frame = tk.Frame(master)
frame.grid(row=0,column=0)
self.buttons = []
for column in range(self.COLUMN_MAX):
buttons = []
for row in range(self.ROW_MAX):
button = tk.Button(frame, command=partial(self.color_change, column, row), height=10, width=25)
button.grid(column=column, row=row)
buttons.append(button)
self.buttons.append(buttons)
def color_change(self, column, row):
self.buttons[column][row]['bg'] = 'red'
print(column, row)
def main():
root = tk.Tk()
app = App(root)
root.mainloop()
if __name__ == '__main__':
main()
Um noch mal ein Beispiel zu geben was bei deinem `self.btn= [[0 for y in range(ymax)]]*3` eigentlich passiert.
(Ich wollte ja ausführlicher antworten, aber das hatte Sirius3 dann schon erledigt.)
Code: Alles auswählen
>>> ymax = 4
>>> btn = [[0 for y in range(ymax)]] * 3
>>> btn
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
>>> btn[1][2] = 3
>>> btn
[[0, 0, 3, 0], [0, 0, 3, 0], [0, 0, 3, 0]]
- __blackjack__
- User
- Beiträge: 14047
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@MissMapeL: Noch eine Kleinigkeit: Listen sind keine Arrays, man sollte sie deswegen auch nicht so nennen. Es gibt in Python auch Arrays, damit sind dann meistens die Datentypen mit diesem Namen aus dem Numpy-Package gemeint.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Vielen Dank für die schnellen Antworten.
Ich werde mir die Kritik ( 4 Leerzeichen pro Ebene, ...) zu Herzen nehmen und gelobe sofortige Besserung.
Bisher habe ich vor allem C# und VB programmiert. Aus diesen Sprachen habe ich die Idee der Arrays übernommen.
Auf zum nächsten Veruch...
Liebe Grüße und Danke an alle!!!
Ich werde mir die Kritik ( 4 Leerzeichen pro Ebene, ...) zu Herzen nehmen und gelobe sofortige Besserung.
Bisher habe ich vor allem C# und VB programmiert. Aus diesen Sprachen habe ich die Idee der Arrays übernommen.
Auf zum nächsten Veruch...
Liebe Grüße und Danke an alle!!!