Is there a cross platform way to get the monitor's refresh rate in python (2.6)? I'm using Pygame and PyOpenGL, if that helps.
I don't need to change the refresh rate, I just need to know what it is.
Is there a cross platform way to get the monitor's refresh rate in python (2.6)? I'm using Pygame and PyOpenGL, if that helps.
I don't need to change the refresh rate, I just need to know what it is.
I am not sure about the platform you use, but on window you can use ctypes or win32api to get details about devices e.g. using win32api
import win32api
def printInfo(device):
print((device.DeviceName, device.DeviceString))
settings = win32api.EnumDisplaySettings(device.DeviceName, -1)
for varName in ['Color', 'BitsPerPel', 'DisplayFrequency']:
print("%s: %s"%(varName, getattr(settings, varName)))
device = win32api.EnumDisplayDevices()
printInfo(device)
output on my system:
\\.\DISPLAY1 Mobile Intel(R) 945GM Express Chipset Family
Color: 0
BitsPerPel: 8
DisplayFrequency: 60
On macOS, you can use pyobjc
to query the refresh rate of all the attached displays. You'll need the Cocoa
(i.e. "AppKit") framework for this:
$ python3 -m venv screen-res
$ . ./screen-res/bin/activate
$ pip install pyobjc-framework-Cocoa
then, in Python:
from AppKit import NSScreen
for each in NSScreen.screens():
print(f"{each.localizedName()}: {each.maximumFramesPerSecond()}Hz")
On my system, this produces:
LG HDR WQHD+: 120Hz
Built-in Retina Display: 120Hz
(Which is correct, my displays are indeed both set to a 120Hz refresh rate.)
On Linux, you can use python-xlib
:
from Xlib import display
from Xlib.ext import randr
d = display.Display()
default_screen = d.get_default_screen()
info = d.screen(default_screen)
resources = randr.get_screen_resources(info.root)
active_modes = set()
for crtc in resources.crtcs:
crtc_info = randr.get_crtc_info(info.root, crtc, resources.config_timestamp)
if crtc_info.mode:
active_modes.add(crtc_info.mode)
for mode in resources.modes:
if mode.id in active_modes:
print(mode.dot_clock / (mode.h_total * mode.v_total))
Associating the appropriate screen index number with the place you want your PyOpenGL window to open up on is left as an exercise for the reader :).
(I won't duplicate Anurag's answer for Windows here, especially since I can't test it, but that's how you would do it on that platform.)
You can use DEVMODEW, but this only works on Windows Machines.
Install 'wmi' using pip with "pip install wmi"
import ctypes
import wmi
from time import sleep
class DEVMODEW(ctypes.Structure): # Defines the DEVMODEW Structure
_fields_ = [
("dmDeviceName", ctypes.c_wchar * 32),
("dmSpecVersion", ctypes.c_uint16),
("dmDriverVersion", ctypes.c_uint16),
("dmSize", ctypes.c_uint32),
("dmDriverExtra", ctypes.c_uint16),
("dmFields", ctypes.c_uint32),
("dmPosition", ctypes.c_int32 * 2),
("dmDisplayOrientation", ctypes.c_uint32),
("dmDisplayFixedOutput", ctypes.c_uint32),
("dmColor", ctypes.c_short),
("dmDuplex", ctypes.c_short),
("dmYResolution", ctypes.c_short),
("dmTTOption", ctypes.c_short),
("dmCollate", ctypes.c_short),
("dmFormName", ctypes.c_wchar * 32),
("dmLogPixels", ctypes.c_uint16),
("dmBitsPerPel", ctypes.c_uint32),
("dmPelsWidth", ctypes.c_uint32),
("dmPelsHeight", ctypes.c_uint32),
("dmDisplayFlags", ctypes.c_uint32),
("dmDisplayFrequency", ctypes.c_uint32),
("dmICMMethod", ctypes.c_uint32),
("dmICMIntent", ctypes.c_uint32),
("dmMediaType", ctypes.c_uint32),
("dmDitherType", ctypes.c_uint32),
("dmReserved1", ctypes.c_uint32),
("dmReserved2", ctypes.c_uint32),
("dmPanningWidth", ctypes.c_uint32),
("dmPanningHeight", ctypes.c_uint32)
]
def get_monitor_refresh_rate():
c = wmi.WMI()
for monitor in c.Win32_VideoController():
return monitor.MaxRefreshRate
return None
refresh_rate = get_monitor_refresh_rate()
if refresh_rate is not None:
print(f"Monitor refresh rate: {refresh_rate} Hz")
else:
print("Cannot Detremine the Monitor Refresh Rate.")
sleep(10)
You can use the pygame clock
fps = 60
clock = pygame.time.Clock()
At the end of the code:
clock.tick(fps)