Python Tkinter в Docker .TclError: не удалось подключиться к дисплею

Я новичок в python и пытаюсь создать небольшое приложение. Это должно быть приложение с графическим интерфейсом, и я хотел поместить его в контейнер с помощью докера. Я получаю следующую ошибку и не могу найти решение

No protocol specified
No protocol specified
Traceback (most recent call last):
  File "tkinker.py", line 7, in <module>
    tinker = Tk()
  File "/usr/lib/python2.7/lib-tk/Tkinter.py", line 1818, in __init__
    self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: couldn't connect to display ":0.0"

Он запускается локально, но не запускается в докере. Моя ОС Xubuntu.

Я создал пример приложения (ниже), см. run-test.sh https://github.com/jeremysells/test/tree/master/docker-tkinter


person Jeremy Sells    schedule 12.09.2016    source источник
comment
Опять же, добавить -e DISPLAY=$DISPLAY недостаточно.   -  person VonC    schedule 12.09.2016
comment
Это может быть специфично для ОС, но я бы так не думал. Кто-нибудь знает, нужно ли мне что-то настраивать локально, чтобы заставить это работать?   -  person Jeremy Sells    schedule 12.09.2016
comment
Извините, я думал, что вы на Mac   -  person VonC    schedule 12.09.2016


Ответы (4)


Как описано здесь, вам потребуется графический слой X11.
Но поскольку вы уже используете '(X)Ubuntu, настройки DISPLAY должно быть достаточно:

export DISPLAY=127.0.0.1:0.0

docker run -it -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix yourImage

Проверьте также XAuthority.

person VonC    schedule 12.09.2016
comment
См. также github.com/docker/docker/issues/8710#issuecomment-71113263, чтобы открыть локальный сокет xquartz на порту TCP. - person VonC; 12.09.2016

Вам нужно будет установить DISPLAY в контейнере. Вы можете добавить его в качестве аргумента в команду запуска docker следующим образом:

docker run -ti -e DISPLAY=$DISPLAY blah-image blah-command

DISPLAY должен быть установлен в оболочке Xubuntu, из которой вы запускаете команду.

person SidJ    schedule 12.09.2016
comment
Говорят, та же проблема # docker run -ti -e DISPLAY=$DISPLAY tkinter-test:latest Traceback (самый последний вызов последним): файл tkinker.py, строка 7, в ‹module› tinker = Tk() File /usr/lib/ python2.7/lib-tk/Tkinter.py, строка 1818, в init self.tk = _tkinter.create(screenName, baseName, className, Interactive, Wantobjects, useTk, sync, use) _tkinter. TclError: не удалось подключиться к дисплею: ​​0.0 - person Jeremy Sells; 12.09.2016
comment
Установлено ли отображение в оболочке, где вы запускаете команду? Можете ли вы запускать графические интерфейсы из-за пределов докера? - person SidJ; 13.10.2016
comment
Да, дисплей включен. Когда я запускаю #echo $DISPLAY, он возвращает: 0.0.0. Интересно, имеет ли это какое-то отношение к xauth (stackoverflow.com/questions/16296753/ и wiki.ros.org/docker/Tutorials/GUI). В данный момент у меня нет свободного времени, поэтому мне придется вернуться к тестированию, когда я это сделаю. - person Jeremy Sells; 27.10.2016
comment
Используйте IP-адрес вашей системы Linux/UNIX (не контейнера Docker). Например, -e DISPLAY=10.0.0.1:0.0 (замените 10.0.0.1 IP-адресом вашей системы Linux/UNIX). - person Dan Anderson; 05.09.2019

Введите xhost + в своем терминале. Затем

docker run --rm \
    --network=host --privileged \
    -v /dev:/dev \
    -e DISPLAY=$DISPLAY \
    -v /tmp/.X11-unix:/tmp/.X11-unix \
    -v $HOME/.Xauthority:/root/.Xauthority \
    -it yourimage

работал на меня. xhost + отключает контроль доступа. После чего клиент может подключаться с любого хоста.

person Dilawar    schedule 15.07.2019
comment
Connect here подразумевает возможность запускать такие вещи, как снимки экрана и регистраторы нажатий клавиш: вы действительно не хотите разрешать эту возможность с любого хоста. - person David Maze; 03.01.2020
comment
Итак, какая лучшая альтернатива, @DavidMaze? - person RayLuo; 11.01.2021

Получено из другого ответа здесь и вдохновлено такой комментарий, мой поиск заканчивается двумя работоспособными решениями. Выберите любой из них, который вы предпочитаете.

  • xhost local:root && docker -e DISPLAY=$DISPLAY -v /tmp/.X11-unix:/tmp/.X11-unix your_image
  • xhost local:root && docker -e DISPLAY=$DISPLAY --net=host your_image
person RayLuo    schedule 17.01.2021