Buttons in Frame (mit fixer Größe) einpassen

Fragen zu Tkinter.
Antworten
thludwig
User
Beiträge: 21
Registriert: Dienstag 23. Juni 2020, 06:39

Hallo zusammen.

Ich habe ein Projekt gestartet, mit dem ich Dartscores erfassen will. Dazu gibt es einen separaten Thread, aber ich hätte hier schon mal eine Frage, die sich gestern aufgetan hat.

Der Aufbau meines Spiel-Bildschirms beinhaltet mehrere Frames. Im mittleren will ich die 3x21 Buttons für die Eingabe der Dartwürfe darstellen. Da ich das Programm für meinen 19"-Touchscreen erstelle, haben die Frames eine feste Größe. Ich platziere die Frames mit PLACE und baue die Buttons mit GRID in den Frame. Der Frame für die Dart-Buttons hat jetzt eine Größe, wo 3 Buttons mit "Buttonwidth" 11 zu klein und 12 zu groß sind....Kommazahlen gehen ja nicht.

Kann ich die Buttons so anlegen, dass sie in den Frame eingepasst werden? Oder, falls das nicht geht, wie kann ich die Buttons über Pixelangabe setzen?

Ich hab nach einer Antwort auf meine Frage gesucht, aber hier im Forum und auch im Netz nix gefunden. Einzig die Funktion FILL in Verbindung mit PACK scheint etwas in dieser Richtung zu sein...aber ich raffe nicht, wie.

Gruß
Thorsten
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

Hallo Thorsten,
kleinere Schrift und width = 12 ?
Gruss Peter
thludwig
User
Beiträge: 21
Registriert: Dienstag 23. Juni 2020, 06:39

Hi Peter.
Das könnte ich natürlich ausprobieren, befürchte allerdings, dass ich dann im gleichen Dilemma stecken werde...dann ist wahrscheinlich 12 zu klein und 13 zu groß ;-)
Weißt du, wie das mit PLACE und dem pixelgenauen Setzen funktioniert? Also dass ich die Größe der Buttons nicht mit "Zeichen" angebe, sondern mit Pixeln?

Ich fürchte tatsächlich, dass die ganze Abfragerei der 63 Buttons und die dazugehörige Zuordnung der Punkte zu den einzelnen Würfen der Spieler eh nicht so hinhaut, wie ich mir das derzeit vorstelle. Ich denke, ich muss da noch etwas mehr gedankliche Vorarbeit leisten.
Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Ich habe mit TK schon ewig nichts mehr gemacht, aber ich empfehle dir, wie bei allen GUI-Toolkits: Verwende die Layoutmanager.
Wenn du anfängst GUI-Elemente Pixelgenau zu setzen, wirst du wahnsinnig. Und schon die kleinste Änderung macht dein komplettes Layout zunichte. Und damit meine ich nicht unbedingt eine Änderung in deinem Programm.
Daher meine klare Empfehlung: Nimm einen Layout-Manager. Das ist am Anfang etwas mehr Arbeit, lohnt sich aber.
thludwig
User
Beiträge: 21
Registriert: Dienstag 23. Juni 2020, 06:39

Ja, kann ich mir gut vorstellen und überall wird auch empfohlen, Pack und Grid dem Place vorzuziehen :)
Zur Not werden die Buttons halt minimal kleiner.

Aber Frames mit Pixelangabe setzen und darin dann den ganzen Rummel mit Pack und Grid zu achen, ist schon ok, oder?
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

thludwig hat geschrieben: Mittwoch 24. Juni 2020, 09:15 dann ist wahrscheinlich 12 zu klein und 13 zu groß ;-)
Die Breite der Buttons wird mit der Anzahl der Schriftzeichen gesetzt, die Höhe mit der Anzahl Zeilen.
Also bewirkt ein kleinere Schrift einen schmaleren Button.

Gruss
Peter
Benutzeravatar
__blackjack__
User
Beiträge: 14085
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@thludwig: Nein auch die Frames mit Pixelangaben setzen ist nicht ok.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
thludwig
User
Beiträge: 21
Registriert: Dienstag 23. Juni 2020, 06:39

OK, auch nicht. Die Größe der Frames (x Pixel breit und y Pixel hoch) auch nicht?

Aber ist das nicht, wenn ich das bisher richtig verstanden habe, recht unflexibel, was die Umsetzung nach meinen Wünschen angeht? Ich habe mir ja ein Bild gezeichnet wie ich mir die Darstellung vorstelle....krieg ich das mit Pack und Grid umgesetzt, ohne Kompromisse eingehen zu müssen?
Wenn ich die Buttons nur mit "x Zeichen Breite" und "y Zeichen Höhe" erstellen kann, wird mir der Platz auf meinem 1280x1024 Pixel großen Bild nicht ausreichen für alle 21 Reihen á 3 Buttons.
Ich habe verstanden, dass damit die darstellung erhalten bleibt, wenn sich die Bildgröße (Fenster? Auflösung) ändert, aber da ich das Programm ja (Stand heute) nur auf meinem 19"-Monitor laufen lassen möchte, ist das doch egal.

Oder was hab ich noch nicht kapiert? Wie kriege ich Python dann dazu, die richtigen Proportionen darzustellen?

Hier ist nochmal das Bild, wie ich mir es vorstelle...

Bild
Benutzeravatar
__blackjack__
User
Beiträge: 14085
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@thludwig: Ich würde mir da einfach erst einmal gar keinen Kopf drum machen und zunächst die relative Anordnung sinnvoll umsetzen. Im äusseren Frame beispielsweise ein 3×3 Grid wobei der Frame mit den vielen Buttons in der Mitte die komplette mittlere Spalte belegt, also mit ``rowspan=3``.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

Hallo Thorsten,
ich weiss nicht genau, was Du auf den Tasten haben willst.
Dein Bild ist nicht zu sehen.
Ein kleines Beispiel von meinem 19" Monitor.
Da ist noch viel Platz frei....

Code: Alles auswählen

#!/usr/bin/env python3 -u
#-*- coding: #utf-8 -*-

from tkinter import Tk, Button, Frame, IntVar
from functools import partial

def erstelle_tastenfeld():        
    root = Tk()    
    oberer_rahmen = Frame(root, width=1050, height=50, bg="cyan", bd=3)
    oberer_rahmen.grid(row=0, column=0, columnspan=3)
    linker_rahmen = Frame(root, width=250, height=700, bg="lightgreen", bd=3)
    linker_rahmen.grid(row=1, column=0, rowspan=2)
    tasten_rahmen = Frame(root, width=680, height=625, bg="yellow", padx=5)
    tasten_rahmen.grid(column=1, row=1)
    rechter_rahmen = Frame(root, width=250, height=700, bg="lightgreen", bd=3)
    rechter_rahmen.grid(row=1, column=2, rowspan=2)
    unterer_rahmen = Frame(root, width=650, height=50, bg="red", bd=3)
    unterer_rahmen.grid(row=2, column=1)
    zaehler = 0
    punkteliste = []
    
    for zeile in range(21):
        for spalte in range(3):
            zaehler += 1
            wert = IntVar()
            if zeile == 0 and spalte == 0:
                wert.set(50)
            elif zeile== 0 and spalte == 1:
                wert.set(25)
            elif zeile == 0 and spalte == 2:
                wert.set(0)
            else: wert.set(64-zaehler)
            print(wert.get())            
            
            button_name = str(wert.get())
            taste = Button(tasten_rahmen, text=button_name, width=5,
                           font=("helvetica", "7"),pady=3, padx=15, bd=5,
                           command=partial(zeige_tastenwert, wert, punkteliste))
            taste.grid(row=zeile, column=spalte)    
            
    root.mainloop()

def zeige_tastenwert(wert, punkteliste):
    tastenwert = wert.get()
    punkteliste.append(tastenwert)
    print("Tastenwert", tastenwert)
    print(punkteliste)
    if len(punkteliste) == 3:
        punkte = punkteliste[0] + punkteliste[1] + punkteliste[2]
        print("Total", punkte)

if __name__ == "__main__":
    erstelle_tastenfeld()
Gruss
Peter
thludwig
User
Beiträge: 21
Registriert: Dienstag 23. Juni 2020, 06:39

Hi Peter.

Vielen Dank für die Mühe ^_^
Ich schau mir das morgen mal genauer an, was du da gemacht hast. Mir ist nur aufgefallen (ich hab den Code einfach mal in Spyder kopiert und gestartet), dass du obendrüber noch einen Frame über die ganze Breite gemacht hast. Das "Tastenfeld" soll von ganz oben nach ganz unten gehen (Auflösung 1280x1024), damit pro Button ich möglichst viel Fläche zum Drauftatschen habe ;)

Könnte ich denn damit auch jeden einzelnen Button abfragen, ob er gedrückt wurde? Also sind die Buttons einzeln auswertbar?

Gruß
Thorsten
Benutzeravatar
peterpy
User
Beiträge: 188
Registriert: Donnerstag 7. März 2013, 11:35

Hallo Thorsten,
Ich hab einfach oben, links, rechts und unten noch ein Frame eingebaut. In diese Frames kannst Du noch viele Elemente (mit grid) einbauen. Und die Tastengrösse lässt sich mit der Schriftgrösse und wenn nötig, mit der Zeilenanzahl einstellen.
Könnte ich denn damit auch jeden einzelnen Button abfragen, ob er gedrückt wurde?
Was meinst Du damit? Wie soll die Software kontrollieren, ob die richtige Taste betätigt wurde?
Die Taste zeigt ja das Betätigen durch den Wechsel des Reliefs an (Borderwidth gross genug wählen).

Du hast ein Touchdisplay, ich habe mit diesen Dinger meine Mühe. Entweder sind meine Finger zu gross oder die Haut zu trocken. Ich benutze zum Bedienen dieser Displays einen Stift. Der hat den Vorteil, dass meine Finger die Taste und deren Reaktion nicht verdecken und den Nachteil, dass dieser Stift immer wieder verschwindet.:-(
Also sind die Buttons einzeln auswertbar?
Probier's aus.

Gruss
Peter
Antworten