├── .gitignore ├── README.md ├── default ├── Dockerfile └── hello.py ├── example-screenshot.png └── qml ├── Dockerfile ├── hello.mp4 ├── hello.py └── hello.qml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # docker-pyqt5 2 | [![](https://images.microbadger.com/badges/image/jozo/pyqt5.svg)](https://microbadger.com/images/jozo/pyqt5 "Get your own image badge on microbadger.com") 3 | 4 | Dockerfile for development of GUI applications with Python 3 + PyQt5 5 | 6 | 7 | **Links**: [GitHub repo](https://github.com/jozo/docker-pyqt5), [Docker Hub](https://hub.docker.com/r/jozo/pyqt5) 8 | 9 | ### Supported tags 10 | * `latest`, `1.0` 11 | * `qml`, `qml-1.0` - Add additional libraries for working with QML (bigger image size) 12 | 13 | ## How to use it on Linux 14 | *Tested on Ubuntu 22.04* 15 | 16 | You can test if everything works with the small testing app included in this 17 | docker image. You can try it with: 18 | 19 | ``` 20 | docker run --rm -it \ 21 | -v /tmp/.X11-unix:/tmp/.X11-unix \ 22 | -e DISPLAY=$DISPLAY \ 23 | -u qtuser \ 24 | jozo/pyqt5 python3 /tmp/hello.py 25 | ``` 26 | 27 | You should see a window similar to this: 28 | 29 | ![Screenshot](example-screenshot.png) 30 | 31 | ## How to use it on MacOS 32 | 1. Install [XQuartz](https://www.xquartz.org). Restart OS. 33 | 2. In XQuartz: Check the option: XQuartz -> Preferences -> Security -> "Allow connections from network clients" 34 | 3. Run in terminal: 35 | ``` 36 | IP=$(ifconfig en0 | grep inet | awk '$1=="inet" {print $2}') 37 | xhost + 38 | ``` 39 | 40 | You can test if everything works with the small testing app included in this 41 | docker image. You can try it with: 42 | 43 | ``` 44 | docker run --rm -it \ 45 | -v /tmp/.X11-unix:/tmp/.X11-unix \ 46 | -e DISPLAY=$IP:0 \ 47 | -u qtuser \ 48 | jozo/pyqt5 python3 /tmp/hello.py 49 | ``` 50 | -------------------------------------------------------------------------------- /default/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | MAINTAINER jozo 4 | 5 | ENV DEBIAN_FRONTEND=noninteractive 6 | 7 | # Add user 8 | RUN adduser --quiet --disabled-password qtuser && usermod -a -G audio qtuser 9 | 10 | # This fix: libGL error: No matching fbConfigs or visuals found 11 | ENV LIBGL_ALWAYS_INDIRECT=1 12 | 13 | # Install Python 3, PyQt5 14 | RUN apt-get update && apt-get install -y python3-pyqt5 15 | 16 | COPY hello.py /tmp/hello.py 17 | -------------------------------------------------------------------------------- /default/hello.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from PyQt5.QtWidgets import QApplication, QWidget, QLabel 3 | 4 | 5 | if __name__ == "__main__": 6 | app = QApplication(sys.argv) 7 | 8 | # Build the window widget 9 | w = QWidget() 10 | w.setGeometry(300, 300, 250, 150) # x, y, w, h 11 | w.setWindowTitle("My First Qt App") 12 | 13 | # Add a label with tooltip 14 | label = QLabel("Hello World", w) 15 | label.setToolTip("This is a QLabel widget with Tooltip") 16 | label.resize(label.sizeHint()) 17 | label.move(80, 50) 18 | 19 | # Show window and run 20 | w.show() 21 | app.exec_() 22 | -------------------------------------------------------------------------------- /example-screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jozo/docker-pyqt5/4893ceead4f358fcef80298d287c0ba9db7cb23d/example-screenshot.png -------------------------------------------------------------------------------- /qml/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM jozo/pyqt5 2 | 3 | MAINTAINER jozo 4 | 5 | # To fix: QGLXContext: Failed to create dummy context 6 | ENV QT_QUICK_BACKEND=software 7 | 8 | # Install additional PyQt5 packages 9 | RUN apt-get update && apt-get install -y \ 10 | python3-pyqt5.qtopengl \ 11 | python3-pyqt5.qtquick \ 12 | python3-pyqt5.qtmultimedia \ 13 | # Install Qml 14 | qmlscene \ 15 | qml-module-qtqml* \ 16 | qml-module-qtquick* \ 17 | qml-module-qmltermwidget \ 18 | qml-module-qt-websockets \ 19 | qml-module-qt3d \ 20 | qml-module-qtaudioengine \ 21 | qml-module-qtav \ 22 | qml-module-qtbluetooth \ 23 | qml-module-qtcharts \ 24 | qml-module-qtdatavisualization \ 25 | qml-module-qtgraphicaleffects \ 26 | qml-module-qtgstreamer \ 27 | qml-module-qtlocation \ 28 | qml-module-qtmultimedia \ 29 | qml-module-qtpositioning \ 30 | # Libraries for multimedia 31 | libqt5multimedia5-plugins \ 32 | gstreamer1.0-libav \ 33 | gstreamer1.0-alsa \ 34 | gstreamer1.0-plugins-bad \ 35 | gstreamer1.0-plugins-base \ 36 | gstreamer1.0-plugins-base-apps \ 37 | gstreamer1.0-plugins-good \ 38 | gstreamer1.0-plugins-ugly \ 39 | alsa-base \ 40 | alsa-utils 41 | 42 | COPY hello.* /tmp/ 43 | -------------------------------------------------------------------------------- /qml/hello.mp4: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jozo/docker-pyqt5/4893ceead4f358fcef80298d287c0ba9db7cb23d/qml/hello.mp4 -------------------------------------------------------------------------------- /qml/hello.py: -------------------------------------------------------------------------------- 1 | import os 2 | import sys 3 | 4 | from PyQt5.QtCore import QUrl 5 | from PyQt5.QtGui import QGuiApplication 6 | from PyQt5.QtQuick import QQuickView 7 | 8 | if __name__ == '__main__': 9 | app = QGuiApplication(sys.argv) 10 | app.setApplicationName("Hello World") 11 | 12 | view = QQuickView() 13 | view.setResizeMode(QQuickView.SizeRootObjectToView) 14 | view.setSource( 15 | QUrl.fromLocalFile(os.path.join(os.path.dirname(__file__), 'hello.qml')) 16 | ) 17 | view.show() 18 | 19 | sys.exit(app.exec_()) 20 | -------------------------------------------------------------------------------- /qml/hello.qml: -------------------------------------------------------------------------------- 1 | import QtQuick 2.0 2 | import QtMultimedia 5.0 3 | 4 | Rectangle { 5 | id: root 6 | width: 500; height: 300 7 | color: "#C9E5AB" 8 | 9 | Text { 10 | anchors { horizontalCenter: parent.horizontalCenter } 11 | text: "Hello! Click below to play video" 12 | } 13 | 14 | Video { 15 | id: video 16 | width : 400 17 | height : 300 18 | source: "hello.mp4" 19 | anchors { horizontalCenter: parent.horizontalCenter } 20 | 21 | MouseArea { 22 | anchors.fill: parent 23 | onClicked: { 24 | video.play() 25 | } 26 | } 27 | 28 | focus: true 29 | Keys.onSpacePressed: video.playbackState == MediaPlayer.PlayingState ? video.pause() : video.play() 30 | Keys.onLeftPressed: video.seek(video.position - 5000) 31 | Keys.onRightPressed: video.seek(video.position + 5000) 32 | } 33 | } 34 | --------------------------------------------------------------------------------