如何确定显示器的刷新率?

发布于 2024-07-30 05:41:40 字数 106 浏览 2 评论 0原文

有没有跨平台的方法来获取Python(2.6)中显示器的刷新率? 我正在使用 Pygame 和 PyOpenGL,如果有帮助的话。

我不需要改变刷新率,我只需要知道它是什么。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

兮子 2024-08-06 05:41:40

我不确定您使用的平台,但在 Windows 上您可以使用 ctypes 或 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)

在我的系统上使用 win32api 输出:

\\.\DISPLAY1 Mobile Intel(R) 945GM Express Chipset Family
Color: 0
BitsPerPel: 8
DisplayFrequency: 60

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
姜生凉生 2024-08-06 05:41:40

您可以使用 pygame 时钟

fps = 60
clock = pygame.time.Clock()

在代码末尾:
时钟.tick(fps)

You can use the pygame clock

fps = 60
clock = pygame.time.Clock()

At the end of the code:
clock.tick(fps)

三生一梦 2024-08-06 05:41:40

在 macOS 上,您可以使用 pyobjc 查询所有附加的刷新率显示。 为此,您需要 Cocoa(即“AppKit”)框架:

$ python3 -m venv screen-res
$ . ./screen-res/bin/activate
$ pip install pyobjc-framework-Cocoa

然后,在 Python 中:

from AppKit import NSScreen

for each in NSScreen.screens():
    print(f"{each.localizedName()}: {each.maximumFramesPerSecond()}Hz")

在我的系统上,这会产生:(

LG HDR WQHD+: 120Hz
Built-in Retina Display: 120Hz

这是正确的,我的显示器确实都设置为 120Hz 刷新)

在 Linux 上,您可以使用 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))

:适当的屏幕索引号以及您希望 PyOpenGL 窗口打开的位置留给读者作为练习:)。

(我不会在这里重复 Anurag 对 Windows 的回答,特别是因为我无法测试它,但这就是您在该平台上执行此操作的方式。)

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

痴意少年 2024-08-06 05:41:40

您可以使用DEVMODEW,但这仅适用于Windows计算机。

使用 pip 和“pip install wmi”安装“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 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)
骷髅 2024-08-06 05:41:40

我建议切换到 pygame社区版。 他们的网站 https://pyga.me/。 长话短说,pygame 前核心开发人员在为原始开发上游做出贡献时遇到了挑战,因此他们分叉了存储库并转移到这个新发行版,旨在提供更频繁的发布、持续的错误修复和增强以及更民主的治理模型(开源的魔力)。 您可以通过运行pip uninstall pygame然后运行pip install pygame-ce --upgrade轻松切换到它。 它们具有与原始 pygame 相同的 API(因此您仍然使用 import pygame 并且一切都保持不变)。

它们有许多不错的新功能和错误修复,包括在 display 模块中获取显示器刷新率的方法:

import pygame

pygame.init()
screen = pygame.display.set_mode((1280, 720))
clock = pygame.time.Clock()
running = True

print(
    "Screen refresh rate for current window:", pygame.display.get_current_refresh_rate()
)  # Must be called after pygame.display.set_mode()
print(
    "Screen refresh rate for all displays:", pygame.display.get_desktop_refresh_rates()
)  # Safe to call before pygame.display.set_mode()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill("purple")

    pygame.display.flip()
    clock.tick(60)  # limits FPS to 60

pygame.quit()

在我的计算机上,此打印

pygame-ce 2.3.2 (SDL 2.26.5, Python 3.11.4)
Screen refresh rate for current window: 144
Screen refresh rate for all displays: [144]

确实是正确的。

I recommend switching to the community edition of pygame. Their website https://pyga.me/. Long story short, the pygame former core developers had challenges contributing to the original development upstream, so they forked the repository and moved to this new distribution that aims to offer more frequent releases, continuous bug fixes and enhancements, and a more democratic governance model (The magic of Open Source). You can easily switch to it by running pip uninstall pygame and then pip install pygame-ce --upgrade. They have the same API as the original pygame (so you still use import pygame and everything remains the same).

They have many nice new features and bug fixes, including methods to get the monitor's refresh rate in the display module:

import pygame

pygame.init()
screen = pygame.display.set_mode((1280, 720))
clock = pygame.time.Clock()
running = True

print(
    "Screen refresh rate for current window:", pygame.display.get_current_refresh_rate()
)  # Must be called after pygame.display.set_mode()
print(
    "Screen refresh rate for all displays:", pygame.display.get_desktop_refresh_rates()
)  # Safe to call before pygame.display.set_mode()

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False

    screen.fill("purple")

    pygame.display.flip()
    clock.tick(60)  # limits FPS to 60

pygame.quit()

On my computer, this prints

pygame-ce 2.3.2 (SDL 2.26.5, Python 3.11.4)
Screen refresh rate for current window: 144
Screen refresh rate for all displays: [144]

which is indeed correct.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文