Jaki jest najprostszy sposób uzyskania rozdzielczości monitora (najlepiej w krotce)?
Tkinter
modułowi możesz to zrobić w ten sposób . Jest częścią standardowej biblioteki Pythona i działa na większości platform Unix i Windows.
Jaki jest najprostszy sposób uzyskania rozdzielczości monitora (najlepiej w krotce)?
Tkinter
modułowi możesz to zrobić w ten sposób . Jest częścią standardowej biblioteki Pythona i działa na większości platform Unix i Windows.
Odpowiedzi:
W systemie Windows:
from win32api import GetSystemMetrics
print("Width =", GetSystemMetrics(0))
print("Height =", GetSystemMetrics(1))
Jeśli pracujesz z ekranem o wysokiej rozdzielczości, upewnij się, że twój interpreter Pythona to HIGHDPIAWARE.
Na podstawie tego postu.
highdpiaware
? Przydałoby się to uwzględnić w odpowiedzi.
W systemie Windows możesz również używać ctypów z GetSystemMetrics()
:
import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
aby nie trzeba było instalować pakietu pywin32; nie potrzebuje niczego, co nie jest dostarczane z samym Pythonem.
W przypadku konfiguracji z wieloma monitorami można pobrać łączną szerokość i wysokość monitora wirtualnego:
import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(78), user32.GetSystemMetrics(79)
GetSystemMetrics(78)
i GetSystemMetrics(79)
wraca?
Stworzyłem moduł PyPI z tego powodu:
pip install screeninfo
Kod:
from screeninfo import get_monitors
for m in get_monitors():
print(str(m))
Wynik:
monitor(1920x1080+1920+0)
monitor(1920x1080+0+0)
Obsługuje środowiska wielomonitorowe . Jego celem jest działanie na wielu platformach; na razie obsługuje Cygwin i X11, ale żądania ściągnięcia są całkowicie mile widziane.
pip install cython pyobjus
), Zanim mogłem go używać na OSX
Jeśli używasz wxWindows, możesz po prostu:
import wx
app = wx.App(False) # the wx.App object must be created first.
print(wx.GetDisplaySize()) # returns a tuple
app = wx.App(False)
przeciwnym razie zostanie wyświetlony komunikat „najpierw należy utworzyć obiekt wx.App”. błąd. 26 głosów i nikt nie sprawdził? Czy działa w systemie Windows bez przypisywania wystąpienia wx do zmiennej?
Zaczerpnięte bezpośrednio z odpowiedzi na ten post: Jak uzyskać rozmiar ekranu w Tkinter?
import tkinter as tk
root = tk.Tk()
screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()
W systemie Windows 8.1 nie otrzymuję prawidłowej rozdzielczości ani z ctypes, ani z tk. Inni ludzie mają ten sam problem z ctypes : getsystemmetrics zwraca nieprawidłowy rozmiar ekranu Aby uzyskać prawidłową pełną rozdzielczość monitora o wysokiej rozdzielczości w systemie Windows 8.1, należy wywołać SetProcessDPIAware i użyć następującego kodu:
import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]
Pełne szczegóły poniżej:
Dowiedziałem się, że dzieje się tak, ponieważ system Windows zgłasza przeskalowaną rozdzielczość. Wygląda na to, że python jest domyślnie aplikacją „obsługującą systemową rozdzielczość dpi”. Typy aplikacji obsługujących DPI są wymienione tutaj: http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor
Zasadniczo zamiast wyświetlać zawartość w pełnej rozdzielczości monitora, co spowodowałoby zmniejszenie czcionek, zawartość jest skalowana w górę, aż czcionki będą wystarczająco duże.
Na moim monitorze otrzymuję:
Rozdzielczość fizyczna: 2560 x 1440 (220 DPI)
Zgłaszana rozdzielczość w języku Python: 1555 x 875 (158 DPI)
W tej witrynie systemu Windows: http://msdn.microsoft.com/en-us/library/aa770067%28v=vs.85%29.aspx Wzór na raportowaną efektywną rozdzielczość systemu to: (raportowany_px * bieżący_dpi) / (96 dpi ) = Physical_px
Jestem w stanie uzyskać poprawną rozdzielczość pełnego ekranu i bieżące DPI za pomocą poniższego kodu. Zauważ, że wywołuję SetProcessDPIAware (), aby umożliwić programowi zobaczenie rzeczywistej rozdzielczości.
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))
Który wrócił:
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
Używam systemu Windows 8.1 z monitorem obsługującym rozdzielczość 220 DPI. Moje skalowanie ekranu ustawia moje obecne DPI na 158.
Użyję 158, aby upewnić się, że moje wykresy w matplotlib mają odpowiedni rozmiar: z pylab import rcParams rcParams ['figure.dpi'] = curr_dpi
Tkinter
to, że używa prawidłowych pikseli, ale nie jest świadomy skalowania dpi, dlatego podaje nieprawidłowe rozmiary mm.
ctypes.windll.shcore.SetProcessDpiAwareness(2)
zwraca błąd OSError: [WinError 126] The specified module could not be found
.
Używając Linuksa, najprostszym sposobem jest wykonanie polecenia bash
xrandr | grep '*'
i analizuje jego wyjście używając regexp.
Możesz to również zrobić przez PyGame: http://www.daniweb.com/forums/thread54881.html
Oto krótki mały program w Pythonie, który wyświetli informacje o konfiguracji wielu monitorów:
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)
Oto przykład jego wyniku:
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()
dostaje gdk_default_root_window
? Czy dlatego jesteś pewien, że .get_screen
zawiera wszystkie monitory?
gtk.Window()
tworzy nowe okno (patrz tutaj ). Okno to tylko sposób get_screen
na uzyskanie informacji o monitorze. Zwraca ekran, na którym okno jest włączone (lub byłoby, gdyby zostało kiedykolwiek wyświetlone). Myślę, że to zależy od konfiguracji X, czy ten "ekran" zawiera wszystkie "monitory". Działa w moim systemie z Twinview.
Używam metody get_screen_resolution w jednym z moich projektów, takim jak ten poniżej, który jest w zasadzie łańcuchem importu. Możesz to zmodyfikować zgodnie ze swoimi potrzebami, usuwając te części, które nie są potrzebne i przesuń bardziej prawdopodobne porty w górę łańcucha.
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)
Stare pytanie, ale go brakuje. Jestem nowy w Pythonie, więc proszę powiedz mi, czy to „złe” rozwiązanie. To rozwiązanie jest obsługiwane tylko w systemach Windows i MacOS i działa tylko na ekranie głównym - ale system operacyjny nie jest wspomniany w pytaniu.
Zmierz rozmiar, wykonując zrzut ekranu. Ponieważ rozmiar ekranu nie powinien się zmieniać, należy to zrobić tylko raz. Są bardziej eleganckie rozwiązania, jeśli masz zainstalowany zestaw narzędzi GUI, taki jak GTK, wx, ...
patrz Poduszka
pip install Pillow
from PIL import ImageGrab
img = ImageGrab.grab()
print (img.size)
Rozwijanie odpowiedzi @ user2366975 , aby uzyskać aktualny rozmiar ekranu w konfiguracji wieloekranowej przy użyciu Tkinter (kod w Pythonie 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
(Powinien działać na wielu platformach, testowany tylko w systemie Linux)
Wypróbuj następujący kod:
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
Jeśli masz zainstalowane PyQt4, wypróbuj następujący kod:
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))
W przypadku PyQt5 będą działać następujące elementy:
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))
Używanie Linuksa Zamiast regexp weź pierwszą linię i wyjmij aktualne wartości rozdzielczości.
Aktualna rozdzielczość wyświetlania: 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
Zrobiono to na xrandr 1.3.5, nie wiem, czy wyjście jest inne w innych wersjach, ale powinno to ułatwić zrozumienie.
Aby uzyskać liczbę bitów na piksel:
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))
parametry w 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,
Wypróbuj pyautogui:
import pyautogui
resolution = pyautogui.size()
print(resolution)
Korzystanie z pygame :
import pygame
pygame.init()
infos = pygame.display.Info()
screen_size = (infos.current_w, infos.current_h)
Jeśli jednak próbujesz ustawić okno na rozmiar ekranu, możesz po prostu zrobić:
pygame.display.set_mode((0,0),pygame.FULLSCREEN)
aby ustawić wyświetlacz w trybie pełnoekranowym. [2]
Możesz użyć PyMouse . Aby uzyskać rozmiar ekranu, użyj screen_size()
atrybutu:
from pymouse import PyMouse
m = PyMouse()
a = m.screen_size()
a
zwróci krotkę, (X, Y)
gdzie X
jest pozycją poziomą a Y
pozycją pionową.
Jeśli pracujesz w systemie operacyjnym Windows, możesz użyć modułu OS, aby go uzyskać:
import os
cmd = 'wmic desktopmonitor get screenheight, screenwidth'
size_tuple = tuple(map(int,os.popen(cmd).read().split()[-2::]))
Zwróci krotkę (Y, X), gdzie Y to rozmiar w pionie, a X to rozmiar w poziomie. Ten kod działa w Pythonie 2 i Pythonie 3
W Linuksie możemy skorzystać z modułu 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())
Jest to trochę kłopotliwe dla ekranu siatkówki, używam tkintera, aby uzyskać fałszywy rozmiar, używam chwytaka pigułki, aby uzyskać rzeczywisty rozmiar:
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
W przypadku późniejszych wersji 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))
Skrypt narzędziowy korzystający z pynput
biblioteki. Publikuję tutaj dla ref .:
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)