welchen Layoutmanager verwenden

Fragen zu Tkinter.
Antworten
udo100
User
Beiträge: 9
Registriert: Freitag 15. Januar 2021, 17:06

Hallo zusammen,
ich möchte mit Tkinter ein Fenster mit 12 Buttons ( 4x4 ) erstellen, welche sich beim vergrößeren des Fensters automatisch in der Größe anpassen.
Dabei sollen die Buttons den gesamten Fensterinhalt ausfüllen.
Mit welchem Layoutmanager macht man dies am besten , ohne externe module? (pack, grid oder place)
Ein kleines Code-Beispiel würde auch helfen.
Danke
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Mit grid. Mit code kann ich am iPad nicht dienen.
udo100
User
Beiträge: 9
Registriert: Freitag 15. Januar 2021, 17:06

mit grid habe ich es schon versucht, aber die Anpassung an die Fenstergröße klappt nicht.
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das tut es ganz bestimmt, wenn man es richtig macht. Da du keinen Code zeigst, kann man auch nicht sehen, was du falsch machst.
juwido
User
Beiträge: 20
Registriert: Donnerstag 15. Dezember 2022, 13:41

Hallo!
Hier: https://tkdocs.com/tutorial/index.html gibt es Infos zu grit. Automatisch geht mit place gar nichts und pack ist zwar etwas einfacher zu benutzen, aber nicht so gut zu kontrollieren, was es macht.
udo100
User
Beiträge: 9
Registriert: Freitag 15. Januar 2021, 17:06

Das ist mein Code.

Code: Alles auswählen

from tkinter import *
class App(Tk):
  def __init__(self):
    super().__init__()

    # configure the root window
    self.title('Memory Game')
    #self.geometry('600x400')
    self.pack_slaves()

    # button grid
    def neues_Spiel():
        spalte = 0
        zeile = 0
        for i in range(16):
            self.btn_name = "button" + str(i)
            self.btn_name = Button(self, text="Karte" + str(i), width=3, height=3)
            self.btn_name.grid(column=spalte, row=zeile)
            if spalte < 3:
                spalte += 1
            else:
                spalte = 0
                zeile += 1
    neues_Spiel()

if __name__ == "__main__":
  app = App()
  app.mainloop()
udo100
User
Beiträge: 9
Registriert: Freitag 15. Januar 2021, 17:06

juwido hat geschrieben: Sonntag 29. Oktober 2023, 17:29 Hallo!
Hier: https://tkdocs.com/tutorial/index.html gibt es Infos zu grit. Automatisch geht mit place gar nichts und pack ist zwar etwas einfacher zu benutzen, aber nicht so gut zu kontrollieren, was es macht.
Danke für den Link., hat mir weiter geholfen.
Jetzt geht es.

Code: Alles auswählen

from tkinter import *
class App(Tk):
  def __init__(self):
    super().__init__()

    # configure the root window
    self.title('Memory Game')
    #self.geometry('600x400')

    # button grid
    def neues_spiel():
        spalte = 0
        zeile = 0
        for i in range(16):
            self.btn_name = "button" + str(i)
            self.btn_name = Button(self, text="Karte" + str(i), width=3, height=3)
            self.btn_name.grid(column=spalte, row=zeile, sticky='nsew')
            if spalte < 3:
                spalte += 1
            else:
                spalte = 0
                zeile += 1
        self.columnconfigure(0, weight=1)
        self.rowconfigure(0, weight=1)
        self.columnconfigure(1, weight=1)
        self.rowconfigure(1, weight=1)
        self.columnconfigure(2, weight=1)
        self.rowconfigure(2, weight=1)
        self.columnconfigure(3, weight=1)
        self.rowconfigure(3, weight=1)
    neues_spiel()

if __name__ == "__main__":
  app = App()
  app.mainloop()
__deets__
User
Beiträge: 14543
Registriert: Mittwoch 14. Oktober 2015, 14:29

Da muss man ein bisschen tricksen, so geht es:

Code: Alles auswählen

from tkinter import *
class App(Tk):
  def __init__(self):
    super().__init__()
    self.columnconfigure(tuple(range(4)), weight=1)
    self.rowconfigure(tuple(range(4)), weight=1)
    # configure the root window
    self.title('Memory Game')
    #self.geometry('600x400')
    self.pack_slaves()

    # button grid
    def neues_Spiel():
        for i in range(16):
            self.btn_name = "button" + str(i)
            self.btn_name = Button(self, text="Karte" + str(i), width=3, height=3)
            self.btn_name.grid(column=i % 4, row=i // 4, sticky="news")
    neues_Spiel()

if __name__ == "__main__":
  app = App()
  app.mainloop()
Basierend auf https://stackoverflow.com/questions/759 ... in-tkinter
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht mal zwei und mal vier.
*-Importe benutzt man nicht. Man definiert keine Funktionen innerhalb von anderen Funktionen.
btn_name erst an einen String zu binden und dann an einen Button ist unsinnig. Wahrscheinlich möchtest Du alle Knöpfe in einer Liste speichern.
Statt spalte und zeile auszurechnen, würde man besser eine doppelte for-Schleife schreiben.

Code: Alles auswählen

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        super().__init__()
        self.title('Memory Game')
        self.buttons = []
        for zeile in range(4):
            for spalte in range(4):
                button = tk.Button(self, text=f"Karte {spalte}/{zeile}", width=3, height=3)
                button.grid(column=spalte, row=zeile, sticky=tk.NSEW)
                self.buttons.append(button)
        for spalte in range(4):
            self.columnconfigure(spalte, weight=1)
        for zeile in range(4):
            self.rowconfigure(zeile, weight=1)

def main():
    app = App()
    app.mainloop()

if __name__ == "__main__":
    main()
udo100
User
Beiträge: 9
Registriert: Freitag 15. Januar 2021, 17:06

wow ..., das sieht um einiges eleganter aus.
Jetzt bräuchte ich nur noch ein vernünftiges event handling der jeweils gedrückten Buttons.
Benutzeravatar
__blackjack__
User
Beiträge: 13116
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@udo100: Da könnte eventuell `functools.partial()` nützlich sein.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
udo100
User
Beiträge: 9
Registriert: Freitag 15. Januar 2021, 17:06

Ih dachte jetzt eher an "widget.bind_all("<Shift-ButtonPress-1>", f)"
Kann man aus dem Event herauslesen welcher Button das event ausgelöst hat?
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Warum shift?
Buttons verhalten sich anders, als einfache Buttonevents, weil Buttons gedrückt und wieder losgelassen werden. Daher benutzt man das command-Argument, und am sinnvollsten, die Position des Buttons an die Aufruffunktion zu übermitteln, geht über functools.partial.
udo100
User
Beiträge: 9
Registriert: Freitag 15. Januar 2021, 17:06

Shift ist natürlich quatsch. Habe functools.partial() nachgelesen aber keinen schimmer was ich damit machen soll.
Das ist für mich als Python-Anfänger noch zu kompliziert. Bin erst seit 2 Wochen dabei. Habe vorher mit Java programmiert.
Aber Danke für die Hinweise.
Antworten