How do I get monitor resolution in Python?

后端 未结 30 1458
深忆病人
深忆病人 2020-11-22 13:49

What is the simplest way to get monitor resolution (preferably in a tuple)?

30条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-22 14:34

    On Windows 8.1 I am not getting the correct resolution from either ctypes or tk. Other people are having this same problem for ctypes: getsystemmetrics returns wrong screen size To get the correct full resolution of a high DPI monitor on windows 8.1, one must call SetProcessDPIAware and use the following code:

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

    Full Details Below:

    I found out that this is because windows is reporting a scaled resolution. It appears that python is by default a 'system dpi aware' application. Types of DPI aware applications are listed here: http://msdn.microsoft.com/en-us/library/windows/desktop/dn469266%28v=vs.85%29.aspx#dpi_and_the_desktop_scaling_factor

    Basically, rather than displaying content the full monitor resolution, which would make fonts tiny, the content is scaled up until the fonts are big enough.

    On my monitor I get:
    Physical resolution: 2560 x 1440 (220 DPI)
    Reported python resolution: 1555 x 875 (158 DPI)

    Per this windows site: http://msdn.microsoft.com/en-us/library/aa770067%28v=vs.85%29.aspx The formula for reported system effective resolution is: (reported_px*current_dpi)/(96 dpi) = physical_px

    I'm able to get the correct full screen resolution, and current DPI with the below code. Note that I call SetProcessDPIAware() to allow the program to see the real resolution.

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

    Which returned:

    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
    

    I am running windows 8.1 with a 220 DPI capable monitor. My display scaling sets my current DPI to 158.

    I'll use the 158 to make sure my matplotlib plots are the right size with: from pylab import rcParams rcParams['figure.dpi'] = curr_dpi

提交回复
热议问题