Unter Windows 8.1 erhalte ich weder von ctypes noch von tk die richtige Auflösung. Andere Benutzer haben das gleiche Problem bei ctypes: getsystemmetrics gibt eine falsche Bildschirmgröße zurück.
Um die korrekte volle Auflösung eines Monitors mit hoher DPI unter Windows 8.1 zu erhalten, muss SetProcessDPIAware aufgerufen und der folgende Code verwendet werden:
import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
Vollständige Details unten:
Ich habe herausgefunden, dass dies daran liegt, dass Windows eine skalierte Auflösung meldet. Es scheint, dass Python standardmäßig eine "System-dpi-fähige" Anwendung ist. Hier sind Arten von DPI-fähigen Anwendungen aufgeführt:
http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor
Anstatt Inhalte in voller Monitorauflösung anzuzeigen, wodurch Schriftarten winzig werden, wird der Inhalt grundsätzlich vergrößert, bis die Schriftarten groß genug sind.
Auf meinem Monitor wird Folgendes angezeigt:
Physikalische Auflösung: 2560 x 1440 (220 DPI)
Gemeldete Python-Auflösung: 1555 x 875 (158 DPI)
Auf dieser Windows-Website: http://msdn.microsoft.com/en-us/library/aa770067%28v=vs.85%29.aspx
Die Formel für die gemeldete effektive Systemauflösung lautet: (gemeldete_px * aktuelle_dpi) / (96 dpi ) = Physical_px
Ich kann die richtige Vollbildauflösung und die aktuelle DPI mit dem folgenden Code erhalten. Beachten Sie, dass ich SetProcessDPIAware () aufrufe, damit das Programm die tatsächliche Auflösung sehen kann.
import tkinter as tk
root = tk.Tk()
width_px = root.winfo_screenwidth()
height_px = root.winfo_screenheight()
width_mm = root.winfo_screenmmwidth()
height_mm = root.winfo_screenmmheight()
# 2.54 cm = in
width_in = width_mm / 25.4
height_in = height_mm / 25.4
width_dpi = width_px/width_in
height_dpi = height_px/height_in
print('Width: %i px, Height: %i px' % (width_px, height_px))
print('Width: %i mm, Height: %i mm' % (width_mm, height_mm))
print('Width: %f in, Height: %f in' % (width_in, height_in))
print('Width: %f dpi, Height: %f dpi' % (width_dpi, height_dpi))
import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
print('Size is %f %f' % (w, h))
curr_dpi = w*96/width_px
print('Current DPI is %f' % (curr_dpi))
Was zurückkam:
Width: 1555 px, Height: 875 px
Width: 411 mm, Height: 232 mm
Width: 16.181102 in, Height: 9.133858 in
Width: 96.099757 dpi, Height: 95.797414 dpi
Size is 2560.000000 1440.000000
Current DPI is 158.045016
Ich verwende Windows 8.1 mit einem 220 DPI-fähigen Monitor. Meine Anzeigeskalierung setzt meine aktuelle DPI auf 158.
Ich werde die 158 verwenden, um sicherzustellen, dass meine Matplotlib-Plots die richtige Größe haben mit: vom Pylab-Import rcParams rcParams ['figure.dpi'] = curr_dpi