Как я могу перечислить подключенные мониторы с xrandr?

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

Тем не менее, у меня сейчас есть проблема; как я могу определить название монитора? Я собирался использовать команду терминала через os.system изменив вывод терминала, чтобы получить требуемый вывод на монитор, а затем сохранив его в программе. К сожалению, несмотря на большие поиски, я не смог выяснить, как я могу это сделать.

Есть ли способ, которым я могу сделать это?

Подводя итог: я ищу терминальную команду, которая дает мне имя монитора, например, VGA1 или же DVI-0

5 ответов

Решение

Я не уверен, как вы собираетесь применять его в своем приложении ("дать пользователю возможность получить желаемое разрешение без использования графических драйверов"), но:

Терминальная команда для отображения списка подключенных экранов

xrandr | grep " connected " | awk '{ print$1 }'

Это даст вам подключенные экраны для дальнейшей обработки, например:

VGA-0
DVI-I-1

Поскольку вы упоминаете python, во фрагменте ниже также будет показан список подключенных экранов:

#!/usr/bin/env python3
import subprocess

def screens():
    output = [l for l in subprocess.check_output(["xrandr"]).decode("utf-8").splitlines()]
    return [l.split()[0] for l in output if " connected " in l]

print(screens())

Это также даст вам подключенные экраны, такие как:

['VGA-0', 'DVI-I-1']

Заметка

Обратите внимание на пробелы вокруг " connected " в искомой строке. Они необходимы для предотвращения несоответствия с disconnected,

Вы можете использовать команду bash с popen:

import os
    list_display = os.popen("xrandr --listmonitors | grep '*' | awk {'print $4'}").read().splitlines()

Ты можешь использовать python и просто python чтобы получить имена подключенных мониторов:

$ python3 -c 'from gi.repository import Gdk; screen=Gdk.Screen.get_default(); \
[print(screen.get_monitor_plug_name(i)) for i in range(screen.get_n_monitors())]'
DP1
LVDS1

Поскольку я не могу добавлять комментарии, я должен добавить полный ответ. Простите за это.

Команда терминала для вывода списка подключенных экранов

ксрандр | grep "подключено" | awk '{напечатать $1}'

Просто небольшая корректировка:

      awk '/\<connected\>/ {print $1}'< <(xrandr)

или же

      xrandr | awk '/\<connected\>/ {print $1}'

awkищет шаблон внутри косой черты/и печатает первый столбец.

Мой первый проект Python находится в стадии разработки, и одна из функций меняет разрешение:


В xrandr маршрут

Как и ты, сначала я все делал в xrandrзвонки из Python. Сегодня я начал переходить на методологию Gnome. Причина в поддержке будущего Wayland plus Mac и MS Windows.

Вот мой xrandr звонки из Python, который отлично работает:

       ''' Create monitors list '''

# Monitor Fields (monitor) within list of all connected (monitors)
monitor = []
MON_X=0; MON_Y=1; MON_W=2; MON_H=3; MON_N=4
# X-offset, Y-offset, width, Height, Monitor Name from `xrandr`
MON_CNT=5
monitors = []
MON_Ndx=0
monitors_cnt = 0

list_display = os.popen("xrandr --listactivemonitors | grep '+' | \
                        awk {'print $3, $4'}").read().splitlines()

for l in list_display:
    monitors_cnt += 1
    # 1920/382x1080/215+3840+2160  eDP-1-1      <---- sample
    # ['3840' '2160' '1920' '1080' 'eDP-1-1']   <---- convert to list
    a = l.split(" ") # Default split on space
    name = a[1]
    b = a[0].split("+")
    x = int (b[1])
    y = int (b[2])
    c = b[0].split("x")
    d = c[0].split("/")
    w = int (d[0])
    d = c[1].split("/")
    h = int (d[0])
    monitors.extend ([x, y, w, h, name])

Gnome был построен не за один день, но...

Gnome был построен не за один день, но... он сгорел в ночном обновлении.

Сказка о двух питонах

Ubuntu не было достаточно сложным для поддержки всех версий, потому что некоторые из них находятся на Python 2, а некоторые - на Python 3. Итак, заголовок вашей программы должен содержать что-то вроде этого:

       try:
    import tkinter as tk
    import tkinter.ttk as ttk
    import tkinter.font as font
    PYTHON_VER="3"
except ImportError: # Python 2
    import Tkinter as tk
    import ttk
    import tkFont as font
    PYTHON_VER="2"

Сказка о двух гномах

С Gnome на Ubuntu 16.04 версия 3.18 но в Ubuntu 18.04 версия Gnome 3.22и то, что работает в 16.04, как следствие, ломается в 18.04. У нас есть два ответа в этой теме:

В ответе Сильвена используются Python 3 и Gnome 3.18 из Ubuntu 16.04:

       [print(screen.get_monitor_plug_name(i)) for i in range(screen.get_n_monitors())]

В ответе Джейкоба также используется Python 3, но используется Gnome 3.22 из Ubuntu 18.04:

       gdkdsp = Gdk.Display.get_default()
for i in range(gdkdsp.get_n_monitors()):
    monitor = gdkdsp.get_monitor(i)

Четыре решения в одном

Мой подход заключается в поддержке Python 2 или Python 3 и Gnome 3.18 или Gnome 3.22:

       def build_monitors_from_gdk():
    monitors = []
    try:
        display = Gdk.Display.get_default()
        try:
            # Gnome 3.22
            num_monitors = display.get_n_monitors()
        except:
            # Gnome 3.18
            screen = display.get_default_screen()
            num_monitors = screen.get_n_monitors()

        for i in range(0, num_monitors):
            try:
                # Gnome 3.22
                monitor = display.get_monitor(i)
                monitor_rect = monitor.get_geometry()
                name = monitor.get_monitor_plug_name()
            except:
                # Gnome 3.18
                monitor_rect = screen.get_monitor_geometry (i)
                name = screen.get_monitor_plug_name(i)

            monitors.append([
                monitor_rect.x,
                monitor_rect.y,
                monitor_rect.width,
                monitor_rect.height,
                name
            ])
    except Exception as e:
        print('Error: error parsing monitors (Gdk)')
        import traceback
        traceback.print_exc()
        monitors = None
    return monitors 

monitors2 = build_monitors_from_gdk()
print (monitors2)

Вывод

       [[0, 0, 1920, 1080, 'HDMI-0'], [1920, 0, 3840, 2160, 'DP-1-1'], [3840, 2160, 1920, 1080, 'eDP-1-1']]

Философия дизайна

Напишите одну программу, которая поддерживает все версии, кроме EOL. Ubuntu 20.04 выйдет в апреле 2020 года, а подсистема Windows для Linux 2 - в мае 2020 года, поэтому я хочу, чтобы мой первый проект Python также поддерживал их.

Другие вопросы по тегам