如何在Python中获取显示器分辨率?

198

获取显示器分辨率的最简单方法是什么(最好返回一个元组)?


您是否使用特定的UI工具包?(例如GTK,wxPython,Tkinter等) - detly
14
使用Tkinter模块,您可以按照这种方式进行操作。它是Python标准库的一部分,在大多数Unix和Windows平台上都可以使用。 - martineau
1
此链接中提供了对常见UI不同技术的良好概述。 - ImportanceOfBeingErnest
33个回答

187

我出于这个原因创建了一个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,但欢迎拉取请求。


4
在Windows上运行正常,但在Mac上我遇到以下错误:ImportError: Could not load X11。 - Chris Lucian
7
在Ubuntu上运行良好。已在Ubuntu 16.04上进行测试。 - Dhruv Reshamwala
5
FYI,Windows DPI缩放仍然适用。这行代码会告诉Windows你想要原始的、未缩放的分辨率:"import ctypes; user32 = ctypes.windll.user32; user32.SetProcessDPIAware()"。1)你的回答很好;做得好。2)我的评论是针对Windows而不是特定库(例如screeninfo)。3)这段代码从KobeJohn在这里的评论中拷贝并测试:https://stackoverflow.com/a/32541666/2616321 - Jason2616321
8
方便的模块(+1)。不过在我使用它之前,我需要在OSX上安装几个要求(例如pip install cython pyobjus)。 - George Profenza
我正在我们的软件中使用它,在Windows上运行得非常好。 - Kostas Markakis
显示剩余2条评论

155

在Windows中,您还可以使用ctypes与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)

17
重要提示:如果使用了DPI缩放(例如在4k显示器上通常是这种情况),则返回的值可能不正确。在初始化GUI组件之前(而不是在调用GetSystemMetrics函数之前),您必须调用SetProcessDPIAware。 对于win32平台上的大多数答案(如GTK等),这也是适用的。 - totaam
2
对于多个显示器,您可以使用GetSystemMetrics(78)和GetSystemMetrics(79)。 - Derek
@Derek GetSystemMetrics(78)GetSystemMetrics(79)分别返回什么? - Stevoisiak
@StevenVascellaro 虚拟屏幕的宽度/高度,以像素为单位。https://msdn.microsoft.com/zh-cn/library/windows/desktop/ms724385(v=vs.85).aspx - Derek

105

在Windows操作系统中:

from win32api import GetSystemMetrics

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

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

参考帖子。


11
要获取多平台完整解决方案,请参考此答案 - Dhruv Reshamwala
4
在使用多个显示器时,这将仅返回主显示器的尺寸。 - Stevoisiak
7
如何将Python解释器设置为“highdpiaware”?这对于回答问题非常有用。 - eric

64

12
如果您将外部显示器扩展到主显示器的旁边,这种方法将给出所有显示器分辨率的总和,而不是当前显示器的分辨率。 - jadelord
查看多屏步骤,请参见我的答案 - norok2
我强烈建议不要使用tkinter。我浪费了很多时间才意识到,如果你在Windows中将屏幕分辨率设置为某个值,但如果文本大小(如在Windows的显示设置中设置的)不是设置为100%,则从tkinter获取的值将按字体大小缩放。例如,分辨率为(3829,2160),文本大小为250%,将报告为(1536,86)。 - Vahid S. Bokharaie

48
如果您正在使用已安装wxPython的wxWindows,则可以简单地执行以下操作:

import wx

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

这是最好的方法...谁没有wx?:)再加上一些代码行,而不是一堆代码在你的眼前。这现在是我的默认方法,谢谢。 - m3nda
1
这应该是app = wx.App(False),否则你会得到“必须先创建wx.App对象”的错误。26个投票,没有人检查吗?在Windows中工作时不需要将wx实例分配给变量吗? - m3nda
5
谁没有微信?很多人吗? - marsh

41

在Windows 8.1中,我无法从ctypes或tk获得正确的分辨率。其他人也遇到了ctypes的同样问题:getsystemmetrics返回错误的屏幕大小

为了获取高DPI显示器的正确全分辨率,在Windows 8.1上,必须调用SetProcessDPIAware并使用以下代码:

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

以下是完整细节:

我发现这是因为Windows报告了一个缩放分辨率。似乎Python默认是一个“系统DPI感知”应用程序。DPI感知应用程序的类型列于此处: 在 Windows 上进行高 DPI 桌面应用程序开发

基本上,与其显示全屏幕分辨率的内容,这会使字体变得很小,而是将内容缩放,直到字体足够大。

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

根据这个 Windows 网站: 为高 DPI 屏幕调整比例。 所报告的系统有效分辨率的公式是:

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

我正在使用一台支持220 DPI的显示器运行Windows 8.1。 我的显示缩放将当前DPI设置为158。

我将使用158来确保我的Matplotlib图表具有正确的大小:

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

1
你提供了很多有用的信息,但是答案本身却被埋在中间。为了让阅读更加容易,你能否先澄清答案是什么,然后再提供背景信息? - skrrgwasme
2
这里的计算似乎存在一个缺陷,如果从报告的宽度和高度(以英寸为单位)计算对角线尺寸,就很容易发现。我的屏幕对角线为13.3英寸,但报告为15英寸。似乎Tkinter使用了正确的像素,但不知道dpi缩放,因此报告了错误的毫米尺寸。 - Primer
这在Windows 10上不起作用,SetSystemDPIAware()似乎没有任何影响。然而,改为调用ctypes.windll.shcore.SetProcessDpiAwareness(2)似乎就可以解决问题了。 - Klamer Schutte
@KlamerSchutte: ctypes.windll.shcore.SetProcessDpiAwareness(2) 返回错误 OSError: [WinError 126] 找不到指定的模块 - Adrian Keister
我在使用Win 7。 - Adrian Keister
显示剩余7条评论

23

为了完整起见,Mac OS X

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

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


20

跨平台且简单的方法是使用随附于几乎所有Python版本的Tkinter,因此您无需安装任何东西:

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

17

如果您正在使用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()

17

虽然这是一个老问题,但却没有解答。我刚开始学习Python,请告诉我这是否是一种“不好”的解决方案。 这个解决方案仅支持Windows和MacOS,并且仅适用于主屏幕 - 但问题中没有提到操作系统。

通过截屏来测量大小。由于屏幕大小不应该改变,因此只需执行一次即可。 如果您安装了GUI工具包(如GTK、wx等),则有更优雅的解决方案。

请参见Pillow

pip install Pillow

from PIL import ImageGrab

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

看起来有点绕,但这里的其他方法也一样不太靠谱。这个方法可行。 :-) - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接