Sous Windows 8.1, je n'obtiens pas la résolution correcte de ctypes ou de tk. D'autres personnes ont le même problème pour les ctypes: getsystemmetrics renvoie une taille d'écran incorrecte
Pour obtenir la résolution complète correcte d'un moniteur à haute résolution sur Windows 8.1, il faut appeler SetProcessDPIAware et utiliser le code suivant:
import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
Détails complets ci-dessous:
J'ai découvert que c'est parce que Windows rapporte une résolution mise à l'échelle. Il semble que python soit par défaut une application «compatible avec le dpi système». Les types d'applications prenant en charge DPI sont répertoriés ici:
http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor
Fondamentalement, plutôt que d'afficher le contenu à la résolution complète du moniteur, ce qui rendrait les polices minuscules, le contenu est mis à l'échelle jusqu'à ce que les polices soient suffisamment grandes.
Sur mon moniteur, j'obtiens:
Résolution physique: 2560 x 1440 (220 DPI)
Résolution python rapportée: 1555 x 875 (158 DPI)
Par ce site Windows: http://msdn.microsoft.com/en-us/library/aa770067%28v=vs.85%29.aspx
La formule pour la résolution effective du système rapportée est: (rapporté_px * courant_dpi) / (96 dpi ) = physical_px
Je peux obtenir la bonne résolution plein écran et le DPI actuel avec le code ci-dessous. Notez que j'appelle SetProcessDPIAware () pour permettre au programme de voir la résolution réelle.
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))
Qui a renvoyé:
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
J'utilise Windows 8.1 avec un moniteur compatible 220 DPI. La mise à l'échelle de mon affichage définit mon DPI actuel sur 158.
Je vais utiliser le 158 pour m'assurer que mes tracés matplotlib sont de la bonne taille avec: from pylab import rcParams rcParams ['figure.dpi'] = curr_dpi