使用跨平台支持的python调整显示分辨率

sj7*_*sj7 13 python windows cross-platform desktop-application screen-resolution

使用python函数调整显示分辨率.它应该是跨平台的,即支持windows,linux和mac(根据操作系统可以有多个案例)

我有代码,我认为在Linux上工作(Ubuntu)我正在寻找一个Windows和Mac的解决方案(应该支持32和64位机器)

def SetResolution(width, height):
    os.popen("xrandr -s "+str(width)+'x'+str(height))
Run Code Online (Sandbox Code Playgroud)

如果有人能告诉我如何获得windows和mac可能的显示分辨率,我也会感激不尽

我在linux上的功能是这样的:

def GetResolutions():
    screen = os.popen("xrandr").readlines()
    possibleResolutions = []
    for a in screen:
        data = a.split()
        if len(data)<4:
            width, height = data[0].split('x')
            fps = re.sub("[^0-9.]", "", data[1])
            possibleResolutions.append({'width':int(width),'height':int(height),'fps':float(fps)})
            if '*' in data[1]:
                currentResolution = {'width':int(width),'height':int(height),'fps':float(fps)}
    return possibleResolutions, currentResolution
Run Code Online (Sandbox Code Playgroud)

tre*_*ddy 7

许多答案已经分散在StackOverflow周围,可以总结如下.

要以纯粹的pythonic方式在Windows上获得分辨率(参考:https://stackoverflow.com/a/3129524/2942522 ):

import ctypes
user32 = ctypes.windll.user32
screensize = user32.GetSystemMetrics(0), user32.GetSystemMetrics(1)
Run Code Online (Sandbox Code Playgroud)

MacOS解决方案也使用Python,但使用标准库之外的包(参考:https://stackoverflow.com/a/3129567/2942522):

import AppKit
[(screen.frame().size.width, screen.frame().size.height)
    for screen in AppKit.NSScreen.screens()]
Run Code Online (Sandbox Code Playgroud)

显然,列表理解将在多显示器设置中迭代屏幕.

我认为Alex Martelli对相关问题(/sf/answers/186402471/)的回应也值得注意.他用:

pygame.display.list_modes()
[(1920, 1080), (1768, 992), (1680, 1050), (1600, 1200), (1600, 1024), (1600, 900
), (1440, 900), (1400, 1050), (1360, 768), (1280, 1024), (1280, 960), (1280, 800
), (1280, 768), (1280, 720), (1152, 864), (1024, 768), (800, 600), (720, 576), (
720, 480), (640, 480)]
Run Code Online (Sandbox Code Playgroud)

获得可用的最大到最小分辨率的列表(尽管pygame如果你走这条路线会成为依赖).相反,我怀疑它在跨平台设置中可以正常工作.此外,他提到pygame.display.set_mode了设置解决方案(文档:http://www.pygame.org/docs/ref/display.html#pygame.display.set_mode).这是以下文档的片段set_mode:

"resolution参数是一对表示宽度和高度的数字.flags参数是其他选项的集合.surth参数表示用于颜色的位数."

也许这会让你开始.至少你可以查看源代码,set_mode看看是否有一些可能的灵感,如果你不能直接使用它.

其他可能有用的想法:

  1. 您可以使用sys.platform(docs:http://docs.python.org/2/library/sys.html#sys.platform)进行粗略的平台检查.这将'darwin'在MacOS上返回.
  2. 可以使用Python platform模块访问位体系结构.如果我platform.architecture()在我的机器上运行它会返回一个元组:('64bit', '')(docs:http://docs.python.org/2/library/platform.html#platform.architecture)


dwu*_*urf 7

以下是适用于Windows的解决方案(取决于pywin32).有些占位符可以放入现有的linux代码,但我不知道如何处理OS X.

from __future__ import print_function
import sys

class ScreenRes(object):
    @classmethod
    def set(cls, width=None, height=None, depth=32):
        '''
        Set the primary display to the specified mode
        '''
        if width and height:
            print('Setting resolution to {}x{}'.format(width, height, depth))
        else:
            print('Setting resolution to defaults')

        if sys.platform == 'win32':
            cls._win32_set(width, height, depth)
        elif sys.platform.startswith('linux'):
            cls._linux_set(width, height, depth)
        elif sys.platform.startswith('darwin'):
            cls._osx_set(width, height, depth)

    @classmethod
    def get(cls):
        if sys.platform == 'win32':
            return cls._win32_get()
        elif sys.platform.startswith('linux'):
            return cls._linux_get()
        elif sys.platform.startswith('darwin'):
            return cls._osx_get()

    @classmethod
    def get_modes(cls):
        if sys.platform == 'win32':
            return cls._win32_get_modes()
        elif sys.platform.startswith('linux'):
            return cls._linux_get_modes()
        elif sys.platform.startswith('darwin'):
            return cls._osx_get_modes()

    @staticmethod
    def _win32_get_modes():
        '''
        Get the primary windows display width and height
        '''
        import win32api
        from pywintypes import DEVMODEType, error
        modes = []
        i = 0
        try:
            while True:
                mode = win32api.EnumDisplaySettings(None, i)
                modes.append((
                    int(mode.PelsWidth),
                    int(mode.PelsHeight),
                    int(mode.BitsPerPel),
                    ))
                i += 1
        except error:
            pass

        return modes

    @staticmethod
    def _win32_get():
        '''
        Get the primary windows display width and height
        '''
        import ctypes
        user32 = ctypes.windll.user32
        screensize = (
            user32.GetSystemMetrics(0), 
            user32.GetSystemMetrics(1),
            )
        return screensize

    @staticmethod
    def _win32_set(width=None, height=None, depth=32):
        '''
        Set the primary windows display to the specified mode
        '''
        # Gave up on ctypes, the struct is really complicated
        #user32.ChangeDisplaySettingsW(None, 0)
        import win32api
        from pywintypes import DEVMODEType
        if width and height:

            if not depth:
                depth = 32

            mode = win32api.EnumDisplaySettings()
            mode.PelsWidth = width
            mode.PelsHeight = height
            mode.BitsPerPel = depth

            win32api.ChangeDisplaySettings(mode, 0)
        else:
            win32api.ChangeDisplaySettings(None, 0)


    @staticmethod
    def _win32_set_default():
        '''
        Reset the primary windows display to the default mode
        '''
        # Interesting since it doesn't depend on pywin32
        import ctypes
        user32 = ctypes.windll.user32
        # set screen size
        user32.ChangeDisplaySettingsW(None, 0)

    @staticmethod
    def _linux_set(width=None, height=None, depth=32):
        raise NotImplementedError()

    @staticmethod
    def _linux_get():
        raise NotImplementedError()

    @staticmethod
    def _linux_get_modes():
        raise NotImplementedError()

    @staticmethod
    def _osx_set(width=None, height=None, depth=32):
        raise NotImplementedError()

    @staticmethod
    def _osx_get():
        raise NotImplementedError()

    @staticmethod
    def _osx_get_modes():
        raise NotImplementedError()


if __name__ == '__main__':
    print('Primary screen resolution: {}x{}'.format(
        *ScreenRes.get()
        ))
    print(ScreenRes.get_modes())
    #ScreenRes.set(1920, 1080)
    #ScreenRes.set() # Set defaults
Run Code Online (Sandbox Code Playgroud)