在没有xrandr的情况下获取Python中每个显示的显示计数和分辨率

时间:2012-01-02 22:07:07

标签: python xlib

我正在运行Ubuntu,我想获得附加显示的数量,它们当前的分辨率,如果可能的话,我们想要相互之间的位置。 因为我不喜欢解析xrandr的控制台输出 - 至少不是我不需要 - 我想用Python-XLib或类似的Pythonic方法来做。

这是我的显示配置的xrandr输出:

$ xrandr
Screen 0: minimum 320 x 200, current 2960 x 1050, maximum 8192 x 8192
DVI-0 connected 1680x1050+0+0 (normal left inverted right x axis y axis) 473mm x 296mm
   1680x1050      60.0*+
   1400x1050      60.0  
   1280x1024      75.0     60.0  
   1440x900       59.9  
   1280x960       75.0     60.0  
   1152x864       75.0  
   1280x720       75.0  
   1024x768       75.1     70.1     60.0  
   832x624        74.6  
   800x600        72.2     75.0     60.3     56.2  
   640x480        72.8     75.0     66.7     60.0  
   720x400        70.1  
VGA-0 connected 1280x1024+1680+26 (normal left inverted right x axis y axis) 376mm x 301mm
   1280x1024      60.0 +   75.0* 
   1024x768       75.1     70.1     60.0  
   832x624        74.6  
   800x600        72.2     75.0     60.3     56.2  
   640x480        72.8     75.0     66.7     60.0  
   720x400        70.1  

我希望用这样的方式获取这些值:

displays = get_displays()
print displays[0].width # out: 1680
print displays[1].width # out: 1280
print displays[0].x_position # out: 0
print displays[1].x_position # out: 1680

当尝试通过Python-XLib(或pyGTK和pygame等其他库)获取信息时,似乎所有显示都始终作为单个显示处理。例如,这是我到目前为止用XLib获得的:

import Xlib
import Xlib.display

display = Xlib.display.Display(':0')

print display.screen_count()        # output: 1
root = display.screen().root
print root.get_geometry().width     # output: 2960 -> no way to get width of single display?
print root.get_geometry().height    # output: 1050

我知道如何获取在Python中调用xrandr的显示信息:

import subprocess
output = subprocess.Popen('xrandr | grep "\*" | cut -d" " -f4',shell=True, stdout=subprocess.PIPE).communicate()[0]

displays = output.strip().split('\n')
for display in displays:
    values = display.split('x')
    width = values[0]
    height = values[1]
    print "Width:" + width + ",height:" + height

但正如我所说,我更喜欢更简洁的方法而无需解析控制台输出。 是否真的没有办法获得(详细)用Python显示信息而不必解析xrandr输出?

4 个答案:

答案 0 :(得分:9)

xrandr只是一个从命令行访问“RandR”X11扩展的客户端。您可以直接从Python-Xlib访问该功能。 Here是一个例子(来自Python-Xlib自己的代码!)。

万一URL再次更改,这里是一段最小的代码,可以让我们看到显示模式。我们需要创建窗口(它与大小无关):

from Xlib import X, display
from Xlib.ext import randr

d = display.Display()
s = d.screen()
window = s.root.create_window(0, 0, 1, 1, 1, s.root_depth)

然后我们可以使用它查询屏幕资源。例如,按照OP的例子:

res = randr.get_screen_resources(window)
for mode in res.modes:
    w, h = mode.width, mode.height
    print "Width: {}, height: {}".format(w, h)

在我的电脑中,我得到了:

$ python minimal.py 
Xlib.protocol.request.QueryExtension
Width: 1600, height: 900
Width: 1440, height: 900
Width: 1360, height: 768
Width: 1360, height: 768
Width: 1152, height: 864
Width: 1024, height: 768
Width: 800, height: 600
Width: 800, height: 600
Width: 640, height: 480

答案 1 :(得分:1)

要获得在Windows中的展示次数,您可以使用

import win32api
print(len(win32api.EnumDisplayMonitors()))

答案 2 :(得分:1)

最新摘要。它会从所有连接的监视器中提取具有当前分辨率的所有模式。

from Xlib import display
from Xlib.ext import randr

def find_mode(id, modes):
   for mode in modes:
       if id == mode.id:
           return "{}x{}".format(mode.width, mode.height)

def get_display_info():
    d = display.Display(':0')
    screen_count = d.screen_count()
    default_screen = d.get_default_screen()
    result = []
    screen = 0
    info = d.screen(screen)
    window = info.root

    res = randr.get_screen_resources(window)
    for output in res.outputs:
        params = d.xrandr_get_output_info(output, res.config_timestamp)
        if not params.crtc:
           continue
        crtc = d.xrandr_get_crtc_info(params.crtc, res.config_timestamp)
        modes = set()
        for mode in params.modes:
            modes.add(find_mode(mode, res.modes))
        result.append({
            'name': params.name,
            'resolution': "{}x{}".format(crtc.width, crtc.height),
            'available_resolutions': list(modes)
        })

    return result

print(get_display_info())

答案 3 :(得分:0)

您只需要 pip3安装Xlib 并使用此代码即可获取信息:

from Xlib import display
d = display.Display()
screen_count = d.screen_count()
default_screen = d.get_default_screen()
for screen in range(0,screen_count):
    info = d.screen(screen)
    print("Screen: %s. Default: %s" % (screen, screen==default_screen))
    print("Width: %s, height: %s" % (info.width_in_pixels,info.height_in_pixels))

从此处获得的属性列表可以在这里找到: http://python-xlib.sourceforge.net/doc/html/python-xlib_16.html#SEC15

使用python Xlib库而不是调用命令行。他们俩都一样。