Seite 1 von 1

Text in Label gleich ausrichten

Verfasst: Freitag 29. Mai 2026, 09:25
von MrCrowncoin
Hallo zusammen,

ich bastle ("basteln" trifft es gut, da es mein erster Kontakt mit Python ist und ich mich an Videos und Anleitungen entlanghangle) an einem GUI für meine Musiksammlung.
Hierfür lese ich mit panda (read.excel) aus einer .xlsx Datei die gewünschten Daten aus und übergebe sie an ein ttk Label.
Das funktioniert inzwischen auch gut, aber die Darstellung gefällt mir nicht.

Zur Veranschaulichung:
Bild

Rechts oben im Label "Musik_gesamt_Ausgabe" kann ich die Formate ausrichten, dafür ist die Anzahl versetzt oder umgedreht.
Unten im Label "Album_label" passt der header im großen und ganzen. Die Spalte "Band" ist noch ausgerichtet aber danach wird es vogelwild.

Kann ich dieses Chaos irgendwie ordnen oder wäre es besser jede Zeile in ein eigenes Label zu überführen?


Ich versuche inzwischen vermutlich länger, dieses Chaos zu ordnen, als der Aufbau des restlichen GUI gedauert hat.

Code: Alles auswählen

....
d = pd.read_excel('Tonträger-Liste.xlsx',sheet_name='Tabelle1',header=0,names=['Band','Titel','Erscheinungsjahr','Format','Herkunft','Limitierug','Bemerkung','Band-korrigiert'])
d_format = d['Format'].value_counts(normalize=False, sort=True)
....
Musik_gesamt_Ausgabe = ttk.Label(root, text=str(d_format.to_string(header=True)), justify="left", font=("Arial", 15),borderwidth=2, relief="solid")
Musik_gesamt_Ausgabe.grid(row=1, column=2, padx=(20, 10), pady=(2, 2), columnspan=3, sticky="e")
....
Album_Input = tk.StringVar(root, value=FoundBand.to_string(header=True,index=False,justify="left", na_rep="---",col_space=15))
Album_label= ttk.Label(root, text=str(Album_Input.get()), justify='left', font=("Arial", 15),borderwidth=2, relief="solid")
Album_label.grid(row=5, column=0, padx=(20, 10), pady=(2, 2), columnspan=3, sticky="ew")
....

Schon mal vorab vielen Dank für die Hilfe.

Re: Text in Label gleich ausrichten

Verfasst: Freitag 29. Mai 2026, 19:21
von kiaralle
Schau mal hier rein. War auch mein Problem :-)

viewtopic.php?t=59039

Re: Text in Label gleich ausrichten

Verfasst: Samstag 30. Mai 2026, 13:56
von snafu
@MrCrowncoin
Deine Daten sind vermutlich mit Tabulatoren (\t) getrennt. Hierdurch kommt aus aufgrund der unterschiedlichen Textlängen zu den verschobenen Spalten. Man sollte also im ersten Schritt zeilenweise alle durch Tabs getrennten Werte per ``.split()`` trennen, dann spaltenweise die Maximalbreiten bestimmen und diese Breiten dann per String Formatting auf die einzelnen Zeilen anwenden.

Wenn du die Ursprungsdaten hier reinstellst, kann ich / wir dir gerne eine Funktion dafür schreiben.

Re: Text in Label gleich ausrichten

Verfasst: Samstag 30. Mai 2026, 15:31
von Sirius3
@snafu: dass man mit Leerzeichen Text rechtsbündig ausrichten kann, geht nur bei Schriftarten mit fester Zeichenbreite. Hier ist die Lösung das Grid-Layout von Tk zu benutzen.

Code: Alles auswählen

import tkinter as tk

CONTENT = [
    ("Format", ""),
    ("CD", "530"),
    ("Digi-CD", "314"),
    ("LP", "211"),
    ("EP", "43"),
    ("MC", "23"),
    ("CD-R", "3"),
]

def main():
    window = tk.Tk()
    totals = tk.Frame(window)
    for index, row in enumerate(CONTENT):
        tk.Label(totals, text=row[0], anchor=tk.W).grid(row=index, column=1, sticky=tk.EW)
        tk.Label(totals, text=row[1], anchor=tk.E).grid(row=index, column=2, sticky=tk.EW)
    totals.pack()
    window.mainloop()

if __name__ == "__main__":
    main()

Re: Text in Label gleich ausrichten

Verfasst: Sonntag 31. Mai 2026, 15:07
von MrCrowncoin
Vielen Dank für die Antworten.

@Sirius3. Das muss ich mir genauer anschauen und ausprobieren. Den Inhalt von CONTENT müsste ich flexibel gestalten. Zumindest die Anzahlen.

@kiaralle, den Beitrag hatte ich in der Vorabsuche sogar gesehen, aber nicht als meine Lösung angesehen. Ich schaue mir das mal näher an.

@snafu die Trennung durch die Tabulatoren müsste dann beim Einlesen der Excel passieren, oder?

Re: Text in Label gleich ausrichten

Verfasst: Sonntag 31. Mai 2026, 18:37
von snafu
Wie liest du die Excel Datei denn ein? Nutzt du Pandas dafür? Bei der Ausgabe kannst du dich durchaus an das Vorgehen von Sirius halten.

Re: Text in Label gleich ausrichten

Verfasst: Montag 1. Juni 2026, 09:21
von snafu
MrCrowncoin hat geschrieben: Sonntag 31. Mai 2026, 15:07 @Sirius3. Das muss ich mir genauer anschauen und ausprobieren. Den Inhalt von CONTENT müsste ich flexibel gestalten. Zumindest die Anzahlen.
Dafür kann man den Code ja anpassen:

Code: Alles auswählen

import tkinter as tk

CONTENT = [
    ("Format", ""),
    ("CD", "530"),
    ("Digi-CD", "314"),
    ("LP", "211"),
    ("EP", "43"),
    ("MC", "23"),
    ("CD-R", "3"),
]

def make_labels(content, master):
    for i, row in enumerate(content):
        for j, string in enumerate(row):
            tk.Label(
                master, text=string, anchor=tk.E if string.isdigit() else tk.W
            ).grid(row=i, column=j, sticky=tk.EW)
    master.pack()

def main():
    window = tk.Tk()
    totals = tk.Frame(window)
    make_labels(CONTENT, totals)
    window.mainloop()

if __name__ == "__main__":
    main()
Hinweis: isdigit() funktioniert nur mit reinen Ziffern ohne Vorzeichen. Negative Zahlen, Kommazahlen und andere Darstellungen erkennt er damit nicht als Zahl. Dafür müsste man sich eine eigene Funktion schreiben:

Code: Alles auswählen

def is_number(string):
    try:
        float(string)
    except ValueError:
        return False
    else:
        return True

Re: Text in Label gleich ausrichten

Verfasst: Montag 1. Juni 2026, 14:17
von __blackjack__
Das `master.pack()` würde ich nicht mit in die Funktion stecken. Das ist nicht deren Aufgabe und ist überraschend für den Leser.

Re: Text in Label gleich ausrichten

Verfasst: Montag 1. Juni 2026, 16:17
von snafu
Das ist tatsächlich etwas schräg. Anbei ein Beispiel, wo die Hilfsfunktion den Frame erstellt und füllt:

Code: Alles auswählen

import tkinter as tk

CONTENT = [
    ["Format"],
    ["CD", "530", "spam"],
    ["Digi-CD", "314", "ham"],
    ["LP", "211", "eggs"],
    ["EP", "43", "foo"],
    ["MC", "23", "bar"],
    ["CD-R", "3", "baz"],
]

def make_frame(master, rows):
    frame = tk.Frame(master)
    for i, row in enumerate(rows):
        for j, string in enumerate(row):
            tk.Label(
                frame, text=string, anchor=tk.E if string.isdigit() else tk.W
            ).grid(row=i, column=j, padx=5, sticky=tk.EW)
    return frame

def main():
    window = tk.Tk()
    make_frame(window, CONTENT).pack(side=tk.LEFT)
    window.mainloop()

if __name__ == "__main__":
    main()

Re: Text in Label gleich ausrichten

Verfasst: Mittwoch 3. Juni 2026, 09:57
von MrCrowncoin
Hallo zusammen,

entschuldigt dass meine Antworten gerne etwas länger dauern. Ich habe leider weniger Zeit für die Bastelei, als ich gerne aufwenden würde.

@Kiaralle
Ich habe einen Moment gebraucht, bis ich verstanden habe, dass Text() mein bisheriges Label() ersetzt.
ABER das funktioniert! Vielen Dank dafür!
Ich muss noch etwas feinjustieren, aber grundsätzlich funktioniert es.

@Snafu & @Sirius3
Auch wenn die Variante von kiaralle aktuell für mich funktioniert, werde ich eure Variante trotzdem auch testen. Da muss ich mich aber definitiv mehr reindenken.
Da ich bei Python am Anfang stehe, bin ich aber froh über jeden Lösungsansatz.
Vielen Dank für eure Hilfe!

Re: Text in Label gleich ausrichten

Verfasst: Mittwoch 3. Juni 2026, 15:29
von snafu
In dem Link wird es ja mit Tabs (\t) gezeigt. Genau das ist doch der Kern deines Problems. Du kannst es eben nicht mit einem einzelnen Tab zwischen den Spalten lösen, weil der Inhalt unterschiedlich lang ist. Das ist genau wie in Word und ähnlichen Programmen.

Wo genau liegt denn noch das Problem? Dass du einen DataFrame vorliegen hast, ergibt sich ja aus deinem eingangs gezeigten Code. Daher hier für Pandas angepasst:

Code: Alles auswählen

import tkinter as tk
import pandas as pd

CONTENT = pd.DataFrame([
    ["Format"],
    ["CD", "530", "spam"],
    ["Digi-CD", "314", "ham"],
    ["LP", "211", "eggs"],
    ["EP", "43", "foo"],
    ["MC", "23", "bar"],
    ["CD-R", "3", "baz"],
])

def make_frame(master, rows):
    frame = tk.Frame(master)
    for i, row in enumerate(rows):
        for j, string in enumerate(row):
            anchor = "e" if string and string.isdigit() else "w"
            tk.Label(
                frame, text=string, anchor=anchor
            ).grid(row=i, column=j, padx=5, sticky="ew")
    return frame

def make_window(rows):
    window = tk.Tk()
    make_frame(window, rows).pack(expand=True)
    window.mainloop()

def main():
    make_window(CONTENT.values)

if __name__ == "__main__":
    main()

Re: Text in Label gleich ausrichten

Verfasst: Mittwoch 3. Juni 2026, 16:13
von snafu
Man kann es halt naiv betrachten und einfach die to_string() Methode des DataFrames benutzen. Nur kommt es dann zu den bereits erwähnten Darstellungsfehlern. Der Trick mit den Leerzeichen klappt nur im Terminal oder anderen Programmen, wo eine feste Zeichenbreite genutzt wird. Das wurde ja bereits angesprochen und ist letztlich nicht zielführend. Außer du willst eine Darstellung in "Schreibmaschinen-Schrift" haben.

Re: Text in Label gleich ausrichten

Verfasst: Mittwoch 3. Juni 2026, 17:53
von grubenfox
snafu hat geschrieben: Mittwoch 3. Juni 2026, 15:29 In dem Link wird es ja mit Tabs (\t) gezeigt. Genau das ist doch der Kern deines Problems. Du kannst es eben nicht mit einem einzelnen Tab zwischen den Spalten lösen, weil der Inhalt unterschiedlich lang ist. Das ist genau wie in Word und ähnlichen Programmen.
Genau dafür sind Tabs doch da: um Texte an festen Spaltenpositionen auszurichten (linksbündig, rechtsbündig, ...), auch wenn die Texte unterschiedliche Längen haben.

Code: Alles auswählen

import tkinter as tk
import pandas as pd

CONTENT = pd.DataFrame([
    ["CD", "530", "spam"],
    ["Digi-CD", "314", "ham"],
    ["LP", "211", "eggs"],
    ["EP", "43", "foo"],
    ["MC", "23", "bar"],
    ["CD-R", "3", "baz"],
])

def make_tabframe(master, rows):
    tabframe = tk.Text(master, font=('arial', 12, 'italic'), border=0, wrap='word', bg="#eaecac", tabs=('3c', tk.RIGHT, '5c', tk.RIGHT))
    tabframe.config(fg="#000000", height=10 ,  width=99,  padx=5, pady=0)
    content = 'Format\n'
    for row in rows:
        line = None
        for string in row:
            if line is None:
                line = string
            else:
                line = f'{line}\t{string}'
        content = f'{content}\n{line}'
    tabframe.insert('0.0', f'{content}')
    return tabframe

def make_window(rows):
    window = tk.Tk()
    make_tabframe(window, rows).pack(expand=True)
    window.mainloop()

def main():
    make_window(CONTENT.values)

if __name__ == "__main__":
    main()
Unschön wird es wenn ein Text länger ist als der Platz zwischen zwei Tab-Positionen. Da ist die Variante mit 'Grid' die flexiblere...

Re: Text in Label gleich ausrichten

Verfasst: Mittwoch 3. Juni 2026, 18:09
von snafu
grubenfox hat geschrieben: Mittwoch 3. Juni 2026, 17:53 Unschön wird es wenn ein Text länger ist als der Platz zwischen zwei Tab-Positionen. Da ist die Variante mit 'Grid' die flexiblere...
Genau darauf wollte ich hinaus. Und die Tabs passen streng genommen auch nur bei spezifischen Font-Einstellungen. Klar wird es im Normalfall häufig passen, aber es gibt eben auch Grenzfälle. Ich würde bei einer GUI-Anwendung jedenfalls nicht auf Tabs setzen.

Und anstelle deines Zusammenstückeln von Strings gibt es bekanntlich die join()-Methode.

Letztlich verbraucht deine Lösung mehr Zeilen bzw. mehr Code, ist weniger robust und IMHO schlechter nachvollziehbar als die Variante mit grid().

Re: Text in Label gleich ausrichten

Verfasst: Mittwoch 3. Juni 2026, 19:48
von Sirius3
Warum werden ein Teil der Parameter direkt beim Anlegen von tk.Text angegen, und ein Teil gleich danach per `config`? Effizienter kann man Strings mit join verknüpfen.

Code: Alles auswählen

def make_tabframe(master, rows):
    tabframe = tk.Text(master,
        font=('arial', 12, 'italic'), 
        border=0,
        wrap='word',
        bg="#eaecac",
        tabs=('3c', tk.RIGHT, '5c', tk.RIGHT),
        fg="#000000",
        height=10,
        width=99,
        padx=5,
        pady=0
    )
    content = '\n'.join("\t".join(row) for row in rows)
    tabframe.insert('0.0', f'Format\n{content}')
    return tabframe

Re: Text in Label gleich ausrichten

Verfasst: Donnerstag 4. Juni 2026, 11:40
von snafu
Wobei ich unabhängig vom tatsächlich verwendeten Widget, die ganzen Style-Angaben als Wörterbuch auslagern und der entsprechenden Funktion übergeben würde. Dann kann man die gewünschte Konfiguration leicht an den verschiedenen Ansätzen ausprobieren und spart sich das Kopieren bzw. doppelte Bearbeiten bei Änderungen.

EDIT: Ist aber gar nicht so trivial wie gedacht, wenn man beide Funktionen abdecken will. Daher nehme ich alles zurück und behaupte (vorläufig) das Gegenteil. :)