Qual è il modo più semplice per ottenere la risoluzione del monitor (preferibilmente in una tupla)?
Tkinter
modulo puoi farlo in questo modo . Fa parte della libreria Python standard e funziona sulla maggior parte delle piattaforme Unix e Windows.
Qual è il modo più semplice per ottenere la risoluzione del monitor (preferibilmente in una tupla)?
Tkinter
modulo puoi farlo in questo modo . Fa parte della libreria Python standard e funziona sulla maggior parte delle piattaforme Unix e Windows.
Risposte:
Su Windows:
from win32api import GetSystemMetrics
print("Width =", GetSystemMetrics(0))
print("Height =", GetSystemMetrics(1))
Se stai lavorando con uno schermo ad alta risoluzione, assicurati che il tuo interprete Python sia HIGHDPIAWARE.
Basato su questo post.
highdpiaware
? Sarebbe utile includerlo nella risposta.
In Windows, puoi anche usare ctypes con GetSystemMetrics()
:
import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
in modo da non dover installare il pacchetto pywin32; non ha bisogno di nulla che non sia fornito con Python stesso.
Per le configurazioni multi-monitor, puoi recuperare la larghezza e l'altezza combinate del monitor virtuale:
import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(78), user32.GetSystemMetrics(79)
GetSystemMetrics(78)
e GetSystemMetrics(79)
restituisce?
Ho creato un modulo PyPI per questo motivo:
pip install screeninfo
Il codice:
from screeninfo import get_monitors
for m in get_monitors():
print(str(m))
Risultato:
monitor(1920x1080+1920+0)
monitor(1920x1080+0+0)
Supporta ambienti multi monitor . Il suo obiettivo è essere multipiattaforma; per ora supporta Cygwin e X11 ma le richieste pull sono totalmente benvenute.
pip install cython pyobjus
) prima di poterlo utilizzare su OSX però
Se stai usando wxWindows, puoi semplicemente fare:
import wx
app = wx.App(False) # the wx.App object must be created first.
print(wx.GetDisplaySize()) # returns a tuple
app = wx.App(False)
altrimenti si ottiene "l'oggetto wx.App deve essere creato prima". errore. 26 voti e nessuno ha controllato? Funziona in Windows senza assegnare l'istanza wx a una variabile?
Tratto direttamente da una risposta a questo post: come ottenere le dimensioni dello schermo in Tkinter?
import tkinter as tk
root = tk.Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
Su Windows 8.1 non ottengo la risoluzione corretta né da ctypes né da tk. Altre persone stanno riscontrando lo stesso problema per ctypes: getsystemmetrics restituisce dimensioni dello schermo errate Per ottenere la risoluzione completa corretta di un monitor con DPI elevato su Windows 8.1, è necessario chiamare SetProcessDPIAware e utilizzare il codice seguente:
import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
Dettagli completi di seguito:
Ho scoperto che questo è dovuto al fatto che Windows riporta una risoluzione ridotta. Sembra che Python sia per impostazione predefinita un'applicazione 'compatibile con i dpi di sistema'. I tipi di applicazioni compatibili con DPI sono elencati qui: http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor
Fondamentalmente, invece di visualizzare il contenuto alla piena risoluzione del monitor, che renderebbe i caratteri minuscoli, il contenuto viene ridimensionato fino a quando i caratteri non sono abbastanza grandi.
Sul monitor ottengo:
Risoluzione fisica: 2560 x 1440 (220 DPI)
Risoluzione python riportata: 1555 x 875 (158 DPI)
Per questo sito Windows: http://msdn.microsoft.com/en-us/library/aa770067%28v=vs.85%29.aspx La formula per la risoluzione effettiva del sistema segnalata è: (reports_px * current_dpi) / (96 dpi ) = physical_px
Sono in grado di ottenere la corretta risoluzione a schermo intero e DPI corrente con il codice seguente. Nota che chiamo SetProcessDPIAware () per consentire al programma di vedere la risoluzione reale.
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))
Che ha restituito:
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
Uso Windows 8.1 con un monitor compatibile con 220 DPI. Il ridimensionamento dello schermo imposta il DPI corrente su 158.
Userò il 158 per assicurarmi che i miei grafici matplotlib siano della giusta dimensione con: from pylab import rcParams rcParams ['figure.dpi'] = curr_dpi
Tkinter
stia utilizzando pixel corretti, ma non è a conoscenza del ridimensionamento dpi, segnalando così dimensioni mm errate.
ctypes.windll.shcore.SetProcessDpiAwareness(2)
restituisce l'errore OSError: [WinError 126] The specified module could not be found
.
Utilizzando Linux, il modo più semplice è eseguire il comando bash
xrandr | grep '*'
e analizza il suo output usando regexp.
Inoltre puoi farlo tramite PyGame: http://www.daniweb.com/forums/thread54881.html
Ecco un piccolo programma Python veloce che mostrerà le informazioni sulla tua configurazione multi-monitor:
import gtk
window = gtk.Window()
# the screen contains all monitors
screen = window.get_screen()
print "screen size: %d x %d" % (gtk.gdk.screen_width(),gtk.gdk.screen_height())
# collect data about each monitor
monitors = []
nmons = screen.get_n_monitors()
print "there are %d monitors" % nmons
for m in range(nmons):
mg = screen.get_monitor_geometry(m)
print "monitor %d: %d x %d" % (m,mg.width,mg.height)
monitors.append(mg)
# current monitor
curmon = screen.get_monitor_at_window(screen.get_active_window())
x, y, width, height = monitors[curmon]
print "monitor %d: %d x %d (current)" % (curmon,width,height)
Ecco un esempio del suo output:
screen size: 5120 x 1200
there are 3 monitors
monitor 0: 1600 x 1200
monitor 1: 1920 x 1200
monitor 2: 1600 x 1200
monitor 1: 1920 x 1200 (current)
gtk.Window()
il gdk_default_root_window
? È così che sei certo che .get_screen
contenga tutti i monitor?
gtk.Window()
fa è creare una nuova finestra (vedi qui ). La finestra è solo un modo da utilizzare get_screen
per ottenere le informazioni sul monitor. Restituisce lo schermo in cui si trova la finestra (o sarebbe, se fosse mai stato visualizzato). Immagino che dipenda dalla configurazione di X se quello "schermo" contiene tutti i "monitor". Lo fa sul mio sistema con Twinview.
Sto usando un metodo get_screen_resolution in uno dei miei progetti come quello qui sotto, che è fondamentalmente una catena di importazione. Puoi modificarlo in base alle tue esigenze rimuovendo quelle parti che non sono necessarie e spostando le porte più probabili verso l'alto nella catena.
PYTHON_V3 = sys.version_info >= (3,0,0) and sys.version_info < (4,0,0):
#[...]
def get_screen_resolution(self, measurement="px"):
"""
Tries to detect the screen resolution from the system.
@param measurement: The measurement to describe the screen resolution in. Can be either 'px', 'inch' or 'mm'.
@return: (screen_width,screen_height) where screen_width and screen_height are int types according to measurement.
"""
mm_per_inch = 25.4
px_per_inch = 72.0 #most common
try: # Platforms supported by GTK3, Fx Linux/BSD
from gi.repository import Gdk
screen = Gdk.Screen.get_default()
if measurement=="px":
width = screen.get_width()
height = screen.get_height()
elif measurement=="inch":
width = screen.get_width_mm()/mm_per_inch
height = screen.get_height_mm()/mm_per_inch
elif measurement=="mm":
width = screen.get_width_mm()
height = screen.get_height_mm()
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
return (width,height)
except:
try: #Probably the most OS independent way
if PYTHON_V3:
import tkinter
else:
import Tkinter as tkinter
root = tkinter.Tk()
if measurement=="px":
width = root.winfo_screenwidth()
height = root.winfo_screenheight()
elif measurement=="inch":
width = root.winfo_screenmmwidth()/mm_per_inch
height = root.winfo_screenmmheight()/mm_per_inch
elif measurement=="mm":
width = root.winfo_screenmmwidth()
height = root.winfo_screenmmheight()
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
return (width,height)
except:
try: #Windows only
from win32api import GetSystemMetrics
width_px = GetSystemMetrics (0)
height_px = GetSystemMetrics (1)
if measurement=="px":
return (width_px,height_px)
elif measurement=="inch":
return (width_px/px_per_inch,height_px/px_per_inch)
elif measurement=="mm":
return (width_px/mm_per_inch,height_px/mm_per_inch)
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
except:
try: # Windows only
import ctypes
user32 = ctypes.windll.user32
width_px = user32.GetSystemMetrics(0)
height_px = user32.GetSystemMetrics(1)
if measurement=="px":
return (width_px,height_px)
elif measurement=="inch":
return (width_px/px_per_inch,height_px/px_per_inch)
elif measurement=="mm":
return (width_px/mm_per_inch,height_px/mm_per_inch)
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
except:
try: # Mac OS X only
import AppKit
for screen in AppKit.NSScreen.screens():
width_px = screen.frame().size.width
height_px = screen.frame().size.height
if measurement=="px":
return (width_px,height_px)
elif measurement=="inch":
return (width_px/px_per_inch,height_px/px_per_inch)
elif measurement=="mm":
return (width_px/mm_per_inch,height_px/mm_per_inch)
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
except:
try: # Linux/Unix
import Xlib.display
resolution = Xlib.display.Display().screen().root.get_geometry()
width_px = resolution.width
height_px = resolution.height
if measurement=="px":
return (width_px,height_px)
elif measurement=="inch":
return (width_px/px_per_inch,height_px/px_per_inch)
elif measurement=="mm":
return (width_px/mm_per_inch,height_px/mm_per_inch)
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
except:
try: # Linux/Unix
if not self.is_in_path("xrandr"):
raise ImportError("Cannot read the output of xrandr, if any.")
else:
args = ["xrandr", "-q", "-d", ":0"]
proc = subprocess.Popen(args,stdout=subprocess.PIPE)
for line in iter(proc.stdout.readline,''):
if isinstance(line, bytes):
line = line.decode("utf-8")
if "Screen" in line:
width_px = int(line.split()[7])
height_px = int(line.split()[9][:-1])
if measurement=="px":
return (width_px,height_px)
elif measurement=="inch":
return (width_px/px_per_inch,height_px/px_per_inch)
elif measurement=="mm":
return (width_px/mm_per_inch,height_px/mm_per_inch)
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
except:
# Failover
screensize = 1366, 768
sys.stderr.write("WARNING: Failed to detect screen size. Falling back to %sx%s" % screensize)
if measurement=="px":
return screensize
elif measurement=="inch":
return (screensize[0]/px_per_inch,screensize[1]/px_per_inch)
elif measurement=="mm":
return (screensize[0]/mm_per_inch,screensize[1]/mm_per_inch)
else:
raise NotImplementedError("Handling %s is not implemented." % measurement)
Vecchia domanda ma manca questa. Sono nuovo in Python quindi per favore dimmi se questa è una soluzione "cattiva". Questa soluzione è supportata solo per Windows e MacOS e funziona solo per la schermata principale, ma il sistema operativo non è menzionato nella domanda.
Misura le dimensioni facendo uno screenshot. Poiché la dimensione dello schermo non dovrebbe cambiare, questa operazione deve essere eseguita una sola volta. Ci sono soluzioni più eleganti se hai installato un toolkit gui come GTK, wx, ....
vedi Cuscino
pip install Pillow
from PIL import ImageGrab
img = ImageGrab.grab()
print (img.size)
Espandendo la risposta di @ user2366975 , per ottenere la dimensione dello schermo corrente in una configurazione multischermo utilizzando Tkinter (codice in Python 2/3):
try:
# for Python 3
import tkinter as tk
except ImportError:
# for Python 2
import Tkinter as tk
def get_curr_screen_geometry():
"""
Workaround to get the size of the current screen in a multi-screen setup.
Returns:
geometry (str): The standard Tk geometry string.
[width]x[height]+[left]+[top]
"""
root = tk.Tk()
root.update_idletasks()
root.attributes('-fullscreen', True)
root.state('iconic')
geometry = root.winfo_geometry()
root.destroy()
return geometry
(Dovrebbe funzionare su più piattaforme, testato solo su Linux)
Prova il codice seguente:
import subprocess
resuls = subprocess.Popen(['xrandr'],stdout=subprocess.PIPE).communicate()[0].split("current")[1].split(",")[0]
width = resuls.split("x")[0].strip()
heigth = resuls.split("x")[1].strip()
print width + "x" + heigth
Se hai installato PyQt4, prova il codice seguente:
from PyQt4 import QtGui
import sys
MyApp = QtGui.QApplication(sys.argv)
V = MyApp.desktop().screenGeometry()
h = V.height()
w = V.width()
print("The screen resolution (width X height) is the following:")
print(str(w) + "X" + str(h))
Per PyQt5, funzionerà quanto segue:
from PyQt5 import QtWidgets
import sys
MyApp = QtWidgets.QApplication(sys.argv)
V = MyApp.desktop().screenGeometry()
h = V.height()
w = V.width()
print("The screen resolution (width X height) is the following:")
print(str(w) + "X" + str(h))
Usare Linux Invece di regexp, prendi la prima riga ed elimina i valori di risoluzione correnti.
Risoluzione corrente del display: 0
>>> screen = os.popen("xrandr -q -d :0").readlines()[0]
>>> print screen
Screen 0: minimum 320 x 200, current 1920 x 1080, maximum 1920 x 1920
>>> width = screen.split()[7]
>>> print width
1920
>>> height = screen.split()[9][:-1]
>>> print height
1080
>>> print "Current resolution is %s x %s" % (width,height)
Current resolution is 1920 x 1080
Questo è stato fatto su xrandr 1.3.5, non so se l'output è diverso su altre versioni, ma questo dovrebbe renderlo facile da capire.
Per ottenere bit per pixel:
import ctypes
user32 = ctypes.windll.user32
gdi32 = ctypes.windll.gdi32
screensize = (user32.GetSystemMetrics(0), user32.GetSystemMetrics(1))
print "screensize =%s"%(str(screensize))
dc = user32.GetDC(None);
screensize = (gdi32.GetDeviceCaps(dc,8), gdi32.GetDeviceCaps(dc,10), gdi32.GetDeviceCaps(dc,12))
print "screensize =%s"%(str(screensize))
screensize = (gdi32.GetDeviceCaps(dc,118), gdi32.GetDeviceCaps(dc,117), gdi32.GetDeviceCaps(dc,12))
print "screensize =%s"%(str(screensize))
parametri in gdi32:
#/// Vertical height of entire desktop in pixels
#DESKTOPVERTRES = 117,
#/// Horizontal width of entire desktop in pixels
#DESKTOPHORZRES = 118,
#/// Horizontal width in pixels
#HORZRES = 8,
#/// Vertical height in pixels
#VERTRES = 10,
#/// Number of bits per pixel
#BITSPIXEL = 12,
Prova pyautogui:
import pyautogui
resolution = pyautogui.size()
print(resolution)
Utilizzando pygame :
import pygame
pygame.init()
infos = pygame.display.Info()
screen_size = (infos.current_w, infos.current_h)
Tuttavia, se stai cercando di impostare la tua finestra sulle dimensioni dello schermo, potresti semplicemente voler fare:
pygame.display.set_mode((0,0),pygame.FULLSCREEN)
per impostare il display in modalità a schermo intero. [2]
Potresti usare PyMouse . Per ottenere le dimensioni dello schermo basta usare l' screen_size()
attributo:
from pymouse import PyMouse
m = PyMouse()
a = m.screen_size()
a
restituirà una tupla,, (X, Y)
dove X
è la posizione orizzontale eY
è la posizione verticale.
Se stai lavorando su un sistema operativo Windows, puoi utilizzare il modulo del sistema operativo per ottenerlo:
import os
cmd = 'wmic desktopmonitor get screenheight, screenwidth'
size_tuple = tuple(map(int,os.popen(cmd).read().split()[-2::]))
Restituirà una tupla (Y, X) dove Y è la dimensione verticale e X è la dimensione orizzontale. Questo codice funziona su Python 2 e Python 3
Su Linux possiamo usare il modulo subprocess
import subprocess
cmd = ['xrandr']
cmd2 = ['grep', '*']
p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
p2 = subprocess.Popen(cmd2, stdin=p.stdout, stdout=subprocess.PIPE)
p.stdout.close()
resolution_string, junk = p2.communicate()
resolution = resolution_string.split()[0]
resolution = resolution.decode("utf-8")
width = int(resolution.split("x")[0].strip())
heigth = int(resolution.split("x")[1].strip())
È un po 'fastidioso per lo schermo retina, io uso tkinter per ottenere la dimensione falsa, uso pilllow grab per ottenere dimensioni reali:
import tkinter
root = tkinter.Tk()
resolution_width = root.winfo_screenwidth()
resolution_height = root.winfo_screenheight()
image = ImageGrab.grab()
real_width, real_height = image.width, image.height
ratio_width = real_width / resolution_width
ratio_height = real_height/ resolution_height
Per le versioni successive di PyGtk:
import gi
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk
display = Gdk.Display.get_default()
n_monitors = display.get_n_monitors()
print("there are %d monitors" % n_monitors)
for m in range(n_monitors):
monitor = display.get_monitor(m)
geometry = monitor.get_geometry()
print("monitor %d: %d x %d" % (m, geometry.width, geometry.height))
Script di utilità che utilizza la pynput
libreria. Inserendo qui per rif .:
from pynput.mouse import Controller as MouseController
def get_screen_size():
"""Utility function to get screen resolution"""
mouse = MouseController()
width = height = 0
def _reset_mouse_position():
# Move the mouse to the top left of
# the screen
mouse.position = (0, 0)
# Reset mouse position
_reset_mouse_position()
count = 0
while 1:
count += 1
mouse.move(count, 0)
# Get the current position of the mouse
left = mouse.position[0]
# If the left doesn't change anymore, then
# that's the screen resolution's width
if width == left:
# Add the last pixel
width += 1
# Reset count for use for height
count = 0
break
# On each iteration, assign the left to
# the width
width = left
# Reset mouse position
_reset_mouse_position()
while 1:
count += 1
mouse.move(0, count)
# Get the current position of the mouse
right = mouse.position[1]
# If the right doesn't change anymore, then
# that's the screen resolution's height
if height == right:
# Add the last pixel
height += 1
break
# On each iteration, assign the right to
# the height
height = right
return width, height
>>> get_screen_size()
(1920, 1080)