Seite 1 von 1

Canvas font

Verfasst: Freitag 14. April 2023, 09:20
von Opa Hansi
Hallo,
ich will Text in einer bestimmten Schriftart ausgeben (Windows). Das funktioniert, soweit keine Leerzeichen im Fontnamen vorhanden sind:
Courier -> kein Problem, Courier New -> wird als Arial ausgegeben. Bei z.B. @MS PGothic passiert gar nichts.
Was ist die Ursache? Sind nur bestimmte Schriftarten erlaubt?

Ich hoffe auf Eure Erfahrung!

Re: Canvas font

Verfasst: Freitag 14. April 2023, 09:56
von __deets__
Ein ewiges Ärgernis, dieses Font-Thema. Was gibt denn https://docs.python.org/3/library/tkint ... t.families aus? Vielleicht ist darin ein Hinweis.

Re: Canvas font

Verfasst: Sonntag 16. April 2023, 08:34
von Opa Hansi
Hallo,
zb: @Microsoft JhengHei Light, Arial, Bahnschrift Light, Courier New, ...
Diese Schriftarten sind alle unter Windows installiert. Wenn ein Font mit Leerzeichen ausgewählt wird, kommt am Leerzeichen eine Fehlermeldung, weil hier die Schriftgröße erwartet wird. Dabei ist es egal, wie der Font übergeben wird.

Re: Canvas font

Verfasst: Sonntag 16. April 2023, 08:47
von sparrow
@Opa Hansi: Hilfreich wäre vielleicht wenn du ein Minimalbeispiel zeigst, dass den Font setzt. Also do, dass man es ausprobieren kann.

Re: Canvas font

Verfasst: Sonntag 16. April 2023, 10:28
von __deets__
Und das tust, worum ich gebeten habe: die konkrete Liste der Fonts, die tkinter kennt, hier zu posten. Es geht darum rauszufinden, wie tkinter diese fonts sieht.

Re: Canvas font

Verfasst: Montag 17. April 2023, 09:44
von peterpy
Hallo Opa Hansi,

wichtig ist, den Namen der Schrift in Anführungszeichen zu setzen und
dass von tkinter das modul font importiert wird
Vor Jahren hab ich mir eine Schriftauswahl geschrieben.
Diese listet die im System bekannten Schriften auf und zeigt die gewählte an.

Code: Alles auswählen

import tkinter as tk
from tkinter import font
from functools import partial

class GUI_Schriftauswahl():
    """
    Erstellt die Gui mit der Beschreibung, den Schriftnamen,
    die Checkboxen zur Auswahl der Schrift und das Anzeigefeld    
    """
    def __init__(self, root):
        """
        verwendung hat die Inhalte None für zeichnen, formblatt fue Formblatt
        Schriften und symbole für Schriften der Symbolerstellung
        """
        self.root = root
        self.checkbutton_dict = {}
        self.schriftsatz = {}
        self.ausgewaehlte_schriften = {}
        self.ls_schriften = []
        self.schriftenliste = []
        self.gewaehlt = ""
        self.gewaehlte_Schrift = ""
        self.root = root
        self.schriften = font.families()
        self.anzeige = tk.StringVar()
        self.unterstrichen = 0
        self.toplevel = tk.Toplevel(self.root)
        self.toplevel.title(("Schriftauswahl"))
        beschrieb = (("Die vom System verfügbaren\n"
                       "Schriften sind aufgelistet.\n\n"
                       "Die anzuwendenden Schriften\n"
                       "auswählen.\n"))
        tk.Label(self.toplevel,text= beschrieb, width=35, relief='ridge', bd=5,
                 bg='lightyellow').pack(pady=5)
        self.rahmen = tk.Frame(self.toplevel, bg='cyan')#, width=1650, height=400)
        self.rahmen.pack()
        self.canvas = tk.Canvas(self.rahmen, bg="yellow", height=450, width=270)
        self.canvas.grid(column=0, row=0, sticky=tk.NW)

        self.felderrahmen = tk.Frame(self.canvas, bg='lightgreen', width=300,
                                     height=400)

        self.canvas.create_window(0, 0, window=self.felderrahmen, anchor='nw')

        self.ybar = tk.Scrollbar(self.rahmen, orient='vertical',
                                 command=self.canvas.yview)
        self.ybar.grid(column=2, row=0, sticky=tk.N+tk.S, padx=5)

        self.canvas.config(yscrollcommand=self.ybar.set)


        self.textfenster = tk.Canvas(self.rahmen, width=300,
                                     height=50, bg='white')
        self.textfenster.grid(row=2, column=0, columnspan=2,
                              pady=5)
        
        self.aufliste_schriften()
        for zeile, schriftart in enumerate(self.ls_schriften):
            self.schriftenliste.append(schriftart)
            self.anzeige_schrift = tk.Label(self.felderrahmen, text=schriftart,
                                         relief="raised", width=30,
                                         anchor="w")
            self.anzeige_schrift.grid(row=zeile, column=1)
            self.checkbutton_variable = tk.IntVar()Opa Hansi
            self.checkbutton_dict[zeile] = self.checkbutton_variable
            self.auswahl_schrift = tk.Checkbutton(self.felderrahmen,
                                    command=partial(self.auswahl, zeile),
                                    variable=self.checkbutton_variable)
            self.auswahl_schrift.grid(row=zeile, column=0, padx=3)

        self.felderrahmen.update_idletasks()
        groesse_anzeigefeld = self.felderrahmen.winfo_geometry()
        dimension_anzeigefeld = groesse_anzeigefeld.split('+')
        breite_hoehe = dimension_anzeigefeld[0].split('x')
        hoehe = breite_hoehe[1]
        self.canvas.config(scrollregion=(0, 0, 0, hoehe))
        self.toplevel.lift(self.root)
        
    def aufliste_schriften(self):
        """
        Setzt die Schriften in eine Menge um die Duplikate zu eliminieren.
        Aus der Menge ird eine sortierte Liste generiert.
        """
        ohne_duplikate = set(self.schriften)
        for schrift in ohne_duplikate:
            self.ls_schriften.append(schrift)
        self.ls_schriften.sort()

    def auswahl(self, zeile):
        """
        Werden Schriften an oder abgewaehlt,
        werden diese in das Dictionary self.ausgewaehlte_schriften
        aufgenommen Respektive gelöscht.
        """
        self.gewaehlte_schrift = self.schriftenliste[zeile]
        self.aktualisiere()
        an_ab_gewaehlt = self.checkbutton_dict[zeile].get()
        if an_ab_gewaehlt == True:
            self.ausgewaehlte_schriften[zeile] = self.gewaehlte_schrift
        else:
            del self.ausgewaehlte_schriften[zeile]    

    def aktualisiere(self):
        """
        Im Anzeigefenster wird die zuletzt gewaehlte Schrift angezeigt.
        """
        id_tuple = self.textfenster.find_all()
        if id_tuple != (): # Pruefung ob schon eine Schrift vorhanden ist
            self.textfenster.delete(id_tuple[0])
        schrift = f'"{self.gewaehlte_schrift}"'
        gewaehlt = self.textfenster.create_text(150, 40,
                                     text=self.gewaehlte_schrift,
                                     font=schrift)


def main():
    root = tk.Tk()    
    auswahl = GUI_Schriftauswahl(root)    
    root.mainloop()


if __name__ == "__main__":
    main()
Gruss Peter

Re: Canvas font

Verfasst: Montag 17. April 2023, 10:09
von __blackjack__
Das ist nicht robust falls in dem Namen " vorkommen. Besser wäre es dort ein Tupel mit dem Namen drin zu übergeben und `tkinter` dann die Wandlung in den entsprechenden Tcl-Wert zu überlassen.

Re: Canvas font

Verfasst: Mittwoch 19. April 2023, 16:02
von Opa Hansi
Ich habe schnell ein Minimalbeispiel geschrieben und siehe da, es funktioniert.
Also sitzt der Fehler vor dem Monitor.
Ich werde jetzt in meinem Code suche, es kann nur etwas ganz einfaches sein!
Erstmal vielen Dank!

Code: Alles auswählen

from tkinter import *
from tkinter import font as fo


def schrift(fenster,olb,eingabe,ftx,w):
        cs=olb.curselection()
        ctab=""
        if len(cs)!=0:                  #Auswahl
                ctab=olb.get(cs)
                eingabe.insert(0,ctab)
                ftx["text"]=ctab
                ftx["font"]=(ctab, 10)
                w.delete("all")
                w.create_text(5,10, text= ctab,anchor="w",fill="blue",font=(ctab, 10))
        else:
                w.delete(all)
                
def prg(fenster):
        olb=Listbox(fenster,height=12,width=29)
        olb.place(x =10, y =10)

        for font in sorted(fo.families()):    
                olb.insert("end",font)

        w = Canvas(fenster, bg="ghostwhite")
        w.place(x =200, y =80, width=300, height=50)
        
        ftx=Label(fenster,anchor="w", compound=TOP,text="",font="Arial 10")
        ftx.place(x =300, y =60, width=200, height=20)
        
        eingabe=Entry(fenster)
        eingabe.place(x=300,y=10,width=100,height=20)

        pb= Button(fenster, text="Schrift wählen", relief="raised",command=lambda:schrift(fenster,olb,eingabe,ftx,w))
        pb.place(x = 300, y = 40, width=100, height=20)

        
def main():
        fenster=fenster=Tk()
        fenster.geometry("512x256+20-20")
        prg(fenster)
        fenster.mainloop()

if __name__=="__main__":

    main()


Re: Canvas font

Verfasst: Mittwoch 19. April 2023, 16:25
von Opa Hansi
Fehler gefunden:
Das ist falsch:

Code: Alles auswählen

fnt=esatz[10][nl+1:]+", "+esatz[10][:nl]
font=(fnt)
so sollte es sein:

Code: Alles auswählen

font=(esatz[10][nl+1:],esatz[10][:nl])
Danke für Eure Mühe!!!

Re: Canvas font

Verfasst: Mittwoch 19. April 2023, 17:59
von Sirius3
@Opa Hansi: eingerückt wird immer mit 4 Leerzeichen pro Ebene, nicht 8.
Benutze keine Abkürzungen, was soll ein olb oder ein flx sein?
*-Importe benutzt man nicht und fo ist auch keine gute Abkürzung für font.
place benutz man nicht. Bei mir klebt da so ein canvas über allem.
In ›schrift‹ wird ctab ein leerer String zugewiesen, aber nie benutzt.

Code: Alles auswählen

import tkinter as tk
from functools import partial

def select_font(fonts, eingabe, font_text, canvas):
    canvas.delete("all")
    font_index = fonts.curselection()
    if font_index:
        fontname = fonts.get(font_index)
        eingabe.insert(0, fontname)
        font_text["text"] = fontname
        font_text["font"] = (fontname, 10)
        canvas.create_text(5, 10, text=fontname,
            anchor="w", fill="blue", font=(fontname, 10))
        
def main():
    fenster = tk.Tk()
    fonts = tk.Listbox(fenster, height=12, width=29)
    fonts.grid(row=0, column=0, padx=5, pady=5, sticky=tk.N)
    frame = tk.Frame()
    frame.grid(row=0, column=1, padx=5, pady=5, sticky=tk.N)

    for fontname in sorted(tk.font.families()):
        fonts.insert("end", fontname)

    eingabe = Entry(frame)
    font_text = tk.Label(frame, anchor="w", compound=tk.TOP, text="", font="Arial 10")
    canvas = tk.Canvas(frame, bg="ghostwhite")
    button = tk.Button(frame, text="Schrift wählen", relief="raised",
        command=partial(select_font, fonts, eingabe, font_text, canvas))
    eingabe.pack()
    button.pack()
    font_text.pack()
    canvas.pack()
    fenster.mainloop()

if __name__=="__main__":
    main()
In Deinem ganzen Code kommt kein ›esatz‹ vor. Was ist denn nl? Wieder so eine kryptische Abkürzung.