2010-05-27 5 views
27

Ich habe ein Python-Skript, das die genaue Größe beliebiger in willkürlichen Zeichensätzen angezeigter Zeichenketten berechnen muss, um einfache Diagramme zu erzeugen. Ich kann es einfach mit Tkinter machen.Warum unterscheiden sich die berechnete Breite und Höhe eines Zeichens in Tkinter in Pixel zwischen den Plattformen?

import Tkinter as tk 
import tkFont 
root = tk.Tk() 
canvas = tk.Canvas(root, width=300, height=200) 
canvas.pack() 
(x,y) = (5,5) 
text = "yellow world" 
fonts = [] 
for (family,size) in [("times",12),("times",24)]: 
    font = tkFont.Font(family=family, size=size) 
    (w,h) = (font.measure(text),font.metrics("linespace")) 
    print "%s %s: (%s,%s)" % (family,size,w,h) 
    canvas.create_rectangle(x,y,x+w,y+h) 
    canvas.create_text(x,y,text=text,font=font,anchor=tk.NW) 
    fonts.append(font) # save object from garbage collecting 
    y += h+5 
tk.mainloop() 

Die Ergebnisse scheinen auf der Version von Python zu hängen und/oder das System:

Python 2.5 Mac 0S X, times 12: (63,12), times 24: (128,24). Python 2.6 Mac OS X, times 12: (64,14), times 24: (127,27). Python 2.6 Windows XP, times 12: (78,19), times 24: (169,36) http://grab.by/grabs/d24a5035cce0d8032ea4e04cb8c85959.png

Nachdem Ned Batchelder erwähnt, entdeckte ich, dass die Größe der Schriften von Plattform zu Plattform unterscheidet . Es kann kein Deal-Breaker sein, solange Sie bei Tkinter bleiben, der mit sich selbst konsistent bleibt. Aber meine tut nicht Verwenden Sie Tkinter, um die tatsächliche Zeichnung durchzuführen: es beruht nur auf seiner Schriftgröße Berechnungen, um eine Ausgabe (in SVG oder als Python-Skript an Nodebox gesendet werden) zu generieren. Und es ist dort, dass die Dinge gehen wirklich falsch:

Output of mocodo http://grab.by/grabs/f67b951d092dd1f4f490e1469a53bca2.png

(.. Bitte sehen Sie die image in real size Beachten Sie, dass die Haupt-Schriftart für diese Ausgänge verwendet wird, ist nicht Times, aber Trebuchet MS)

ich jetzt vermuten dass solche Diskrepanzen mit Tkinter nicht vermieden werden können. Welche andere plattformübergreifende Lösung würden Sie empfehlen?

+1

Haben Sie Screenshots des Textes in diesen Schriftart nehmen, und vergleichen sie mit den Werten, die Sie bekommen? –

+0

Ich sehe nicht, welche Art von "Cross-Plattform" -Lösung Sie haben möchten ... verschiedene Plattformen und unterschiedliche Hardware verwenden verschiedene Font-Auflösungen und Font-Rendering-Algorithmen. Ich glaube kaum, dass man für alle eine konstante Antwort bekommen könnte. –

+1

Bitte aktualisieren Sie die Bilder, wenn Sie können, wie sie jetzt weg sind. – Nae

Antwort

19

Sie haben zwei Probleme. Lassen Sie uns sie einer nach dem anderen angehen

1: der Unterschied zwischen Python 2.5 und 2.6 auf der gleichen Plattform mit der gleichen Schriftart

Diese beiden Versionen von Python verschiedene Versionen von tk verwenden. Auf meiner Mac-Box verwendet 2.5 die tk-Version 8.4.19 und 2.6 8.5.7. In der Version 8.5.2 von tk wurden einige Änderungen an den Font-Messfunktionen von tk vorgenommen. Unter der Annahme, dass die Änderungen Verbesserungen waren, kann man davon ausgehen, dass die Zahlen, die Sie von Python 2.6 erhalten, genauer sind als die von 2.5.

2: Der Unterschied zwischen Python 2.6 auf dem Mac und 2.6 auf dem PC.

Offensichtlich verwendet der PC von den Screenshots, die Sie einschließen, eine größere Schriftart und Sie erhalten größere Zahlen für die Messung. Die Frage ist, warum? Sie geben die Schriftgröße in Punkten (1/72 Zoll) an. Damit Tk (oder irgendein Rendering-System) die Schriftart rendern kann, muss es wissen, wie viele Pixel in einem Inch auf der tatsächlichen Anzeige sind. Dies wird auf verschiedenen Systemen variieren, und Tk erhält nicht immer eine genaue Zahl von dem zugrunde liegenden Betriebssystem, um seine Berechnungen durchzuführen.

In der Vergangenheit haben Apple und Microsoft 72ppi und 96ppi unabhängig von der tatsächlichen Anzeige standardisiert, so dass die Zahlen immer unterschiedlich sein werden. Weitere Informationen zu den Unterschieden in der Berechnung der Pixeldichte durch Mac und Windows finden Sie im Artikel auf Wikipedia unter Dots Per Inch.

Sie könnten versuchen, dies zu lösen, indem Sie eine Schriftart in Pixel anstatt in Punkten angeben.Sie können dies tun, indem Sie negative Zahlen für die Schriftgröße verwenden.

Schließlich, eine Sache, die Sie Ihrem kleinen Beispielcode hinzufügen können, ist das Ergebnis des Befehls font.actual() auszudrucken - Sie könnten etwas anderes zwischen Ihren Fenstern und Mac-Boxen sehen, was die Unterschiede dort erklären würde. Dadurch erfahren Sie genau, welche Schriftart von Tk verwendet wird.

+0

Vielen Dank für deine Antwort! Du hast mich dazu gebracht, die beiden Probleme zu verstehen und zu beheben. Die erste Version kam von meiner Version von Python 2.6: nämlich 2.6.1, die tatsächlich einen Regressionsfehler bezüglich der Schriftart hat metrics: die Aktualisierung auf Python 2.6.5 war die einfache Lösung Das zweite Problem verschwand auch, als ich negative Zahlen verwendete, um die Schriftgröße anzugeben Havior wurde eigentlich in der Tk-Dokumentation unter http://www.tcl.tk/man/tcl8.4/TkCmd/tk.htm erklärt, was ich nicht wusste. Alle Steine ​​jetzt und ich bin sehr dankbar! – Aristide

+0

@Aristide: Wenn meine Antwort oder eine andere Antwort Ihnen hilft, denken Sie bitte daran, die Antwort als "akzeptiert" zu markieren - es ist ein Teil Ihrer Pflicht als Fragesteller. –

+0

Ihre Antwort hat mir geholfen. Ich habe es bereits als nützlich markiert, aber für den Rest meiner Pflicht sagt das System immer wieder: "Du kannst diese Antwort annehmen und dein Kopfgeld in 10 Stunden vergeben". Ich nehme an, dass es eine minimale Verzögerung von 24h gibt. Bitte seien Sie versichert, ich werde es morgen gerne wiederholen! – Aristide

5

Sie haben nichts falsch gemacht: die Größe der Schriftarten unterscheidet von Plattform zu Plattform.

Ich bin mir nicht sicher, warum die Python-Version zählt, aber die Unterschiede sind nur ein Pixel, so dass es unterschiedliche Rundungen oder unterschiedliche Rendering der gleichen Schriftart sein könnte.

+2

die Python-Version zählt, weil die TK-Version wichtig ist - Schriftmaße zwischen tk 8.4.x und 8.5.x (die Versionen von Python 2.5 und 2.6, –

6

Nach der Suche nach Alter habe ich endlich einen Weg gefunden, um die Breite eines Textes in jeder Schriftart und Größe zu erhalten!

from tkinter import * 

Window = Tk() 
Window.geometry("500x500+80+80") 

frame = Frame(Window) # this will hold the label 
frame.pack(side = "top") 

# CALCULATE: 
measure = Label(frame, font = ("Purisa", 10), text = "The width of this in pixels is.....", bg = "yellow") 
measure.grid(row = 0, column = 0) # put the label in 
measure.update_idletasks() # this is VERY important, it makes python calculate the width 
width = measure.winfo_width() # get the width 

# PROOF IT WORKS: 
canvas = Canvas(frame, width = 400, height = 200, bg = "light green") 
canvas.grid(row = 1, column = 0, columnspan = 100) # collumnspan is 100 so that the line lines up with the text 
line = canvas.create_line(0, 10, width, 10, width = 4) # make a line the same length as the text 
canvas.create_text(10, 20, font = ("Purisa", 10), text = "... "+str(width)+" Pixels", anchor = "nw") 

Die Zeile, die ich mache, ist der Beweis, dass dies für jede Schriftart funktioniert.

Ich habe dies für verschiedene Schriftarten und Größen getestet, soweit ich weiß, dass es funktioniert.

Dies ist ein Bild der Ausgabe: This is a picture of the output

+0

das wird alle Benutzer stoppen, die es lustig finden, WWWWWWWWWWWW einzugeben, damit es nicht auf den Bildschirm passt !!!!!!!!!!! –