如何在 Python 中获得监视器分辨率?

获得监视器分辨率的最简单方法是什么(最好是元组) ?

276210 次浏览

在 Windows 上:

from win32api import GetSystemMetrics


print("Width =", GetSystemMetrics(0))
print("Height =", GetSystemMetrics(1))

如果使用的是高分辨率屏幕,请确保 Python 解释器是 HIGHDPIAWARE。

基于 这个的职位。

使用 Linux,最简单的方法是执行 Bash 命令

xrandr | grep '*'

并使用正则表达式解析其输出。

你也可以通过 玩玩而已: Pygame-获取屏幕大小做到这一点

如果你正在使用 wxWindows,你可以简单的做:

import wx


app = wx.App(False) # the wx.App object must be created first.
print(wx.GetDisplaySize())  # returns a tuple

在 Windows 中,还可以将 ctype 与 GetSystemMetrics()一起使用:

import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)

这样你就不需要安装 pywin32软件包了; 它不需要任何不是 Python 自带的东西。

对于多显示器设置,您可以检索虚拟显示器的合并宽度和高度:

import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(78), user32.GetSystemMetrics(79)

为了完整起见,我们来看看 Mac OS X

import AppKit
[(screen.frame().size.width, screen.frame().size.height)
for screen in AppKit.NSScreen.screens()]

将给出一个包含所有屏幕大小的元组列表(如果存在多个显示器)

使用 Linux

不使用正则表达式,取出第一行并取出当前的分辨率值。

当前显示分辨率: 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

这是在 xrandr 1.3.5上完成的,我不知道其他版本的输出是否不同,但是这应该很容易找到。

X 视窗 版本:

#!/usr/bin/python


import Xlib
import Xlib.display


resolution = Xlib.display.Display().screen().root.get_geometry()
print str(resolution.width) + "x" + str(resolution.height)

直接摘自 在 Tkinter 我怎样才能得到屏幕尺寸邮报的回复,

import tkinter as tk


root = tk.Tk()


screen_width = root.winfo_screenwidth()
screen_height = root.winfo_screenheight()

如果您正在使用 QT工具包,特别是 PySide,您可以执行以下操作:

from PySide import QtGui
import sys


app = QtGui.QApplication(sys.argv)
screen_rect = app.desktop().screenGeometry()
width, height = screen_rect.width(), screen_rect.height()

我正在我的一个项目中使用 get _ screen _ decision 方法,如下面的项目,它基本上是一个导入链。您可以根据您的需要修改这一点,删除那些不需要的部分,并将更有可能的端口向上移动到链中。

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)

下面是一个快速的小 Python 程序,它将显示有关多显示器设置的信息:

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)

下面是它的输出的一个例子:

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)

获取每个像素的位:

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))

参数 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,

在 Windows 8.1上,我无法从 ctype 或 tk 获得正确的分辨率。其他人对 ctype 也有同样的问题: Getsystem 指标返回错误的屏幕大小

要在 Windows 8.1上获得高 DPI 监视器的正确完整分辨率,必须调用 SetProcessDPIAware 并使用以下代码:

import ctypes
user32 = ctypes.windll.user32
user32.SetProcessDPIAware()
[w, h] = [user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)]

详情如下:

我发现这是因为窗口报告的是缩放分辨率。在默认情况下,python 是一个“系统 dpi 感知”应用程序。这里列出了感知新闻部的应用程序类型: 基于 Windows 的高 DPI 桌面应用开发

基本上,不是显示内容的完整的监视器分辨率,这将使字体很小,内容被放大,直到字体足够大。

我在显示器上看到:
物理分辨率: 2560 x 1440(220 DPI)
报告的 Python 分辨率: 1555x875(158DPI)

每个 Windows 站点: 调整高 DPI 屏幕的尺度。 报告系统有效解决办法的公式如下:

(report _ px * current _ dpi)/(96 dpi) = Physical _ px

我能够得到正确的全屏分辨率,当前的 DPI 与下面的代码。 注意,我调用 SetProcessDPIAware ()以允许程序查看真正的分辨率。

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))

结果是:

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

我正在运行 Windows 8.1与220 DPI 能力的监视器。 我的显示缩放设置我当前的 DPI 为158。

我将使用158来确保我的 Matplotlib 图的大小是正确的:

from pylab import rcParams
rcParams['figure.dpi'] = curr_dpi

我创建 PyPI 模块就是为了这个原因:

pip install screeninfo

密码:

from screeninfo import get_monitors
for m in get_monitors():
print(str(m))

结果:

Monitor(x=3840, y=0, width=3840, height=2160, width_mm=1420, height_mm=800, name='HDMI-0', is_primary=False)
Monitor(x=0, y=0, width=3840, height=2160, width_mm=708, height_mm=399, name='DP-0', is_primary=True)

它支持多显示器环境 。它的目标是跨平台; 目前它支持 Cygwin 和 X11,但是完全欢迎 pull 请求。

如果您已经安装了 PyQt4,请尝试以下代码:

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))

对于 PyQt5,以下代码将起作用:

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))

在 Linux 上:

import subprocess
import re


def getScreenDimensions():
xrandrOutput = str(subprocess.Popen(['xrandr'], stdout=subprocess.PIPE).communicate()[0])
matchObj = re.findall(r'current\s(\d+) x (\d+)', xrandrOutput)
if matchObj:
return (int(matchObj[0][0]), int(matchObj[0][1]))


screenWidth, screenHeight = getScreenDimensions()
print(f'{screenWidth} x {screenHeight}')

试试 pyautogui:

import pyautogui
resolution = pyautogui.size()
print(resolution)

老问题了,但这个不见了。 我是新的巨蟒,所以请告诉我,如果这是一个“坏”的解决方案。 这个解决方案只支持 Windows 和 MacOS,它只适用于主屏幕-但操作系统在问题中没有提到。

通过截图测量尺寸。由于截图大小不应该改变,这只能做一次。 如果您安装了 GTK、 wx 等 GUI 工具包,那么还有更优雅的解决方案。

枕头

pip install Pillow

from PIL import ImageGrab


img = ImageGrab.grab()
print (img.size)

使用 xrandr的另一个版本:

import re
from subprocess import run, PIPE


output = run(['xrandr'], stdout=PIPE).stdout.decode()
result = re.search(r'current (\d+) x (\d+)', output)
width, height = map(int, result.groups()) if result else (800, 600)

使用 玩具:

import pygame
pygame.init()
infos = pygame.display.Info()
screen_size = (infos.current_w, infos.current_h)

[1]

然而,如果你想设置你的窗口为屏幕的大小,你可能只想做:

pygame.display.set_mode((0,0),pygame.FULLSCREEN)

将显示设置为全屏模式

你可以使用 PyMouse。要获得屏幕大小只需使用 screen_size()属性:

from pymouse import PyMouse
m = PyMouse()
a = m.screen_size()

a将返回一个元组 (X, Y),其中 X是水平位置,Y是垂直位置。

链接到文档中的函数

在 Linux 上我们可以使用子进程模块

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())

这是一个有点麻烦的视网膜屏幕,我使用 tkinter 得到假的大小,使用枕头抓取得到真正的大小:

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

如果你正在使用 Windows 操作系统,你可以使用操作系统模块来获得它:

import os
cmd = 'wmic desktopmonitor get screenheight, screenwidth'
size_tuple = tuple(map(int,os.popen(cmd).read().split()[-2::]))

它将返回一个元组 (Y,X),其中 为什么是垂直大小,X是水平大小。这段代码适用于 Python2和 Python3

更新

对于 Windows 8/8.1/10,上述答案不起作用,改用下一个:

import os
cmd = "wmic path Win32_VideoController get CurrentVerticalResolution,CurrentHorizontalResolution"
size_tuple = tuple(map(int,os.popen(cmd).read().split()[-2::]))

展开 @ user2366975的答案,使用 Tkinter (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

(应该跨平台工作,仅在 Linux 上测试)

一种跨平台且简单的方法是使用几乎所有 Python 版本的 奇特,这样您就不必安装任何东西:

import tkinter
root = tkinter.Tk()
root.withdraw()
WIDTH, HEIGHT = root.winfo_screenwidth(), root.winfo_screenheight()

对于 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))

对于 Linux,您可以使用以下方法:

import gi
gi.require_version("Gdk", "3.0")
from gi.repository import Gdk


s = Gdk.Screen.get_default()
screen_width = s.get_width()
screen_height = s.get_height()
print(screen_width)
print(screen_height)

使用 pynput库的实用脚本:


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)

许多这样的答案使用 tkinter 来查找屏幕高度/宽度(分辨率) ,但有时需要知道屏幕的 DPI是否与跨平台兼容。 这个答案来自这个 链接,并作为一个评论留在 另一个帖子,但它需要几个小时的搜索才能找到。我还没有与它有任何问题,但请让我知道,如果它不工作在您的系统!

import tkinter
root = tkinter.Tk()
dpi = root.winfo_fpixels('1i')

相关文件显示:

winfo_fpixels(number)
# Return the number of pixels for the given distance NUMBER (e.g. "3c") as float

距离数字是一个数字后跟一个单位,所以3c 表示3厘米,该函数给出屏幕3厘米上的像素数(就像在这里发现的一样)。 为了得到 dpi,我们要求函数显示1英寸屏幕中的像素数(“1i”)。

尝试使用 pyautogui.size()

import pyautogui #pip install pyautogui


x = pyautogui.size()[0] # getting the width of the screen
y = pyautogui.size()[1] # getting the height of the screen


print(x,y)

我想我发现了使用支持多显示器(https://pypi.org/project/mss/)的无依赖库 mss的跨平台:

import mss
sct=mss.mss()
sct.monitors

然后你会得到这样的结果:

[{'left': -1440, 'top': 0, 'width': 4000, 'height': 1080},
{'left': 0, 'top': 0, 'width': 2560, 'height': 1080},
{'left': -1440, 'top': 180, 'width': 1440, 'height': 900}]

元素0是组合所有监视器的虚拟屏幕。元素1是主监视器,元素2是第二个监视器。