Zeilenumbruch im Canvas Label

Fragen zu Tkinter.
Antworten
Benutzeravatar
Cybernuschel
User
Beiträge: 7
Registriert: Donnerstag 12. Mai 2022, 13:39

Liebe Pythongemeinde,

ich habe eine einfache Anfängerfrage.
Wie bekomme ich einen Zeilenumbruch in einem Label hin?
Hier mein kleiner Beispielcode.

Code: Alles auswählen

from tkinter import *
import random

tkFenster = Tk()
tkFenster.title('Test © 2024')
fenster01 = Canvas(tkFenster, width = 400, height = 400, bg ="#F0FFFF")
fenster01.grid()

ergebnis = "Dieser Text ist für das Label leider viel zu lang."

w01_label_Einser = Label(master=tkFenster, bg='#87CEFA', text=ergebnis)
w01_label_Einser.place(x=100, y=100, width=120, height=27)

tkFenster.mainloop()


Vielen Dank

Cybernuschel
Benutzeravatar
DeaD_EyE
User
Beiträge: 1081
Registriert: Sonntag 19. September 2010, 13:45
Wohnort: Hagen
Kontaktdaten:

Man könnte manuell Zeilenumbrüche einfügen. Man könnte auch die vergebene Breite (width) auslassen, wodurch das Label dann an den Text angepasst wird.

Code: Alles auswählen

from tkinter import *
import random

tkFenster = Tk()
tkFenster.title('Test © 2024')
fenster01 = Canvas(tkFenster, width = 400, height = 400, bg ="#F0FFFF")
fenster01.grid()

ergebnis = "Dieser Text ist für\ndas Label\nleider viel zu lang."

w01_label_Einser = Label(master=tkFenster, bg='#87CEFA', text=ergebnis)
w01_label_Einser.place(x=100, y=100, width=120, height=80)

tkFenster.mainloop()
Ohne Zeilenumbruch und ohne Vorgabe der Höhe und Breite:

Code: Alles auswählen

from tkinter import *
import random

tkFenster = Tk()
tkFenster.title('Test © 2024')
fenster01 = Canvas(tkFenster, width = 400, height = 400, bg ="#F0FFFF")
fenster01.grid()

ergebnis = "Dieser Text ist für das Label leider viel zu lang."

w01_label_Einser = Label(master=tkFenster, bg='#87CEFA', text=ergebnis)
w01_label_Einser.place(x=100, y=100)

tkFenster.mainloop()

sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server
Benutzeravatar
__blackjack__
User
Beiträge: 13424
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Cybernuschel: Daran wird ein Zeilenumbruch nichts ändern, weil die 27 Pixel Höhe ja auch schon viel zu wenig Platz für zwei Zeilen ist. Absolute Positions- und Grössenangaben in Pixeln sind halt fast immer ein Problem und sollten nicht gemacht werden. Wenn schon absolute Positions- und Grössenangaben, dann wenigstens in einer ”physikalischen” Grösse, unabhängig von der Monitorauflösung.

Und dann gibt man die Labelgrösse nicht vor, weil man dann ja nie so wirklich weiss ob der Text da nun rein passt oder nicht. Man kann angeben ab welcher Breite der Text umgebrochen werden soll. Da bitte dann auch eine ”physikalische” Grösse und nicht in Pixeln.

Sonstige Anmerkungen zum Quelltext: Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 140 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.

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

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (PascalCase).

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.

Man nummeriert keine Namen. Dann will man sich entweder bessere Namen überlegen, oder gar keine Einzelnamen/-werte verwenden, sondern eine Datenstruktur. Oft eine Liste.

Man muss aber auch gar nicht jedes Zwischenergebnis an einen Namen binden und auch keine Werte die danach gar nicht mehr gebraucht werden.

`random` wird importiert, aber nirgends verwendet.

Hier ein 10×10 cm grosser Canvas mit einem maximal 4 cm breiten Label an Position (3, 3) in cm:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk


def main():
    fenster = tk.Tk()
    fenster.title("Test © 2024")

    canvas = tk.Canvas(fenster, width="10c", height="10c", bg="#F0FFFF")
    canvas.grid()

    tk.Label(
        canvas,
        bg="#87CEFA",
        text="Dieser Text ist für das Label leider viel zu lang.",
        wraplength="4c",
    ).place(x="3c", y="3c")

    fenster.mainloop()


if __name__ == "__main__":
    main()

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Benutzeravatar
Cybernuschel
User
Beiträge: 7
Registriert: Donnerstag 12. Mai 2022, 13:39

Erstmal vielen Dank für die schnellen Antworten, echt super.
Das ich in meinem Code eine zu geringe Höhe von 27 Pixel Höhe angegeben habe, ist natürlich mein Fehler. In meine Orginalprogrammcode ist der natürlich größer. Eine feste Pixel-Breite habe ich angegeben, weil ich mehrere Labels als eine Art Tabelle zusammenfügen will, wo nun mal alle Labels die gleiche Länge haben sollen. Bei __blackjack__User bedanke ich mich ausdrücklich für die Vorlage. Die werden ich erstmal durcharbeiten.

Liebe Grüße Cybernuschel
Benutzeravatar
__blackjack__
User
Beiträge: 13424
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Für Tabellen eignet sich doch das Grid-Layout ganz gut.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Sven_TKLOOP
User
Beiträge: 10
Registriert: Freitag 16. August 2024, 14:10

Hi,

du kannst ein '\n' in ein Label einbauen, dadurch wird ein Zeilenumbruch erzeugt.
Mehr musst du eigentlich gar nicht machen.

Beispiel:

Code: Alles auswählen

ergebnis = "Dieser Text ist\nfür das Label\nleider viel zu lang."
Hoffe das hilft dir weiter.
Benutzeravatar
__blackjack__
User
Beiträge: 13424
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Sven_TKLOOP: Da hat man dann aber immer noch das Problem das man nicht weiss *wo* man die Zeilenumbrüche setzen sollte und wie hoch das Label dann sein muss. Wenn man die Labelbreite in einer ”physikalischen” Grösse angibt, und dass umgebrochen werden soll, dann erledigt diese ganze Berechnungen Tk selbstständig.

Code: Alles auswählen

    **** COMMODORE 64 BASIC V2 ****
 64K RAM SYSTEM  38911 BASIC BYTES FREE
   CYBERPUNX RETRO REPLAY 64KB - 3.8P
READY.
█
Sven_TKLOOP
User
Beiträge: 10
Registriert: Freitag 16. August 2024, 14:10

__blackjack__ hat geschrieben: Sonntag 18. August 2024, 12:17 @Sven_TKLOOP: Da hat man dann aber immer noch das Problem das man nicht weiss *wo* man die Zeilenumbrüche setzen sollte und wie hoch das Label dann sein muss. Wenn man die Labelbreite in einer ”physikalischen” Grösse angibt, und dass umgebrochen werden soll, dann erledigt diese ganze Berechnungen Tk selbstständig.
Ja das stimmt, manuell kanns je nach Anwendung schwierig sein. Aber wie du meintest, macht das Tk selbstständig.
Mit wraplength eigentlich kein Problem.
Benutzeravatar
Cybernuschel
User
Beiträge: 7
Registriert: Donnerstag 12. Mai 2022, 13:39

Nochmal Vielen Dank für eure Antworten. Ich merke doch wie anfängerhaft ich beim Thema Canvas bzw. Tkinter bin.
Ein '\n' in ein Label einbauen um dadurch einen Zeilenumbruch erzeugen war auch meine Idee, klappte aber nicht.
Das man Positionen von Labels in ”physikalischen” Größe war mir neu und ich werde versuchen es anzuwenden.

Gruß euer Cybernuschel
Antworten