Получить количество просмотров и разрешение для каждого дисплея в Python без xrandr

Я запускаю Ubuntu, и я хочу получить количество подключенных дисплеев, их текущее разрешение и, если возможно, их позицию по отношению друг к другу. Потому что мне не нравится разбор консольного вывода xrandr - по крайней мере, нет, если мне это не нужно - я хотел бы сделать это с помощью Python-XLib или аналогичный подход Питонов.

Это вывод 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  

Я хочу получить эти значения с помощью Python, следующим образом:

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

Я знаю, как получить отображаемую информацию, вызывающую xrandr в Python:

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?

Ответ 1

xrandr - это просто клиент для доступа к расширению RandR X11 из командной строки. Вы можете получить доступ к функциональности прямо из Python-Xlib. Вот пример (из собственного кода 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

Ответ 2

Чтобы получить количество отображений в окнах, вы можете использовать

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