Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

silx.gui, silx view: Updated default Qt binding to Pyside6; CI: Updated config #4170

Draft
wants to merge 13 commits into
base: main
Choose a base branch
from
Draft
33 changes: 33 additions & 0 deletions .github/actions/setup-system/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: 'Setup Linux'
description: 'Install system packages and setup Intel Opencl ICD'

runs:
using: "composite"
steps:
# Install packages:
# OpenCL lib
# xvfb to run the GUI test headless
# libegl1-mesa: Required by Qt xcb platform plugin
# libgl1-mesa-glx: For OpenGL
# xserver-xorg-video-dummy: For OpenGL
# libxkbcommon-x11-0, ..: needed for Qt plugins
- name: Install system packages
if: runner.os == 'Linux'
shell: bash
run: |
sudo apt-get update
sudo apt-get install ocl-icd-opencl-dev xvfb libegl1-mesa libgl1-mesa-glx xserver-xorg-video-dummy libxkbcommon-x11-0 libxkbcommon0 libxkbcommon-dev libxcb-icccm4 libxcb-image0 libxcb-shm0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-sync1 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxcb-cursor0 libxcb1

- name: Setup Intel OpenCL ICD
if: runner.os == 'Linux'
shell: bash
run: |
wget -nv http://www.silx.org/pub/OpenCL/intel_opencl_icd-6.4.0.38.tar.gz -O - | tar -xzvf -
echo $(pwd)/intel_opencl_icd/icd/libintelocl.so > intel_opencl_icd/vendors/intel64.icd
echo "OCL_ICD_VENDORS=$(pwd)/intel_opencl_icd/vendors/intel64.icd" >> "$GITHUB_ENV"

- name: Setup OpenGL
if: runner.os == 'Windows'
shell: bash
run: |
C:\\msys64\\usr\\bin\\wget.exe -nv -O $(python -c 'import sys, os.path; print(os.path.dirname(sys.executable))')\\opengl32.dll http://www.silx.org/pub/silx/continuous_integration/opengl32_mingw-mesa-x86_64.dll
28 changes: 12 additions & 16 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,54 +22,52 @@ jobs:
- os: ubuntu-20.04
python-version: "3.8"
QT_API: PyQt5
with_opencl: false
- os: ubuntu-latest
python-version: "3.11"
QT_API: PyQt6
with_opencl: true
- os: ubuntu-latest
python-version: "3.12"
QT_API: PySide6
with_opencl: true

- os: macos-13
python-version: "3.10"
QT_API: PyQt5
with_opencl: true
- os: macos-13
python-version: "3.12"
QT_API: PyQt6
with_opencl: true
- os: macos-13
python-version: "3.9"
QT_API: PySide6
with_opencl: true

- os: windows-latest
python-version: "3.9"
QT_API: PyQt5
with_opencl: false
- os: windows-latest
python-version: "3.12"
QT_API: PyQt6
with_opencl: false
- os: windows-latest
python-version: "3.10"
QT_API: PySide6
with_opencl: false

steps:
- uses: actions/checkout@v4

# Install packages:
# OpenCL lib and icd
# xvfb to run the GUI test headless
# libegl1-mesa: Required by Qt xcb platform plugin
# libgl1-mesa-glx: For OpenGL
# xserver-xorg-video-dummy: For OpenGL
# libxkbcommon-x11-0, ..: needed for Qt plugins
- name: Install system packages
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install ocl-icd-opencl-dev intel-opencl-icd xvfb libegl1-mesa libgl1-mesa-glx xserver-xorg-video-dummy libxkbcommon-x11-0 libxkbcommon0 libxkbcommon-dev libxcb-icccm4 libxcb-image0 libxcb-shm0 libxcb-keysyms1 libxcb-randr0 libxcb-render-util0 libxcb-render0 libxcb-shape0 libxcb-sync1 libxcb-xfixes0 libxcb-xinerama0 libxcb-xkb1 libxcb-cursor0 libxcb1

- uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
cache: "pip"

- uses: ./.github/actions/setup-system

- name: Install build dependencies
run: |
pip install --upgrade --pre build cython setuptools wheel
Expand All @@ -94,8 +92,6 @@ jobs:
env:
QT_API: ${{ matrix.QT_API }}
SILX_TEST_LOW_MEM: "False"
SILX_OPENCL: ${{ matrix.with_opencl && 'True' || 'False' }}
run: |
if [ ${{ runner.os }} == 'Windows' ]; then
export WITH_GL_TEST=False
fi
python -c "import silx.test, sys; sys.exit(silx.test.run_tests(verbosity=1, args=['--qt-binding=${{ matrix.QT_API }}']));"
15 changes: 8 additions & 7 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ jobs:
with:
python-version: "3.12"
cache: "pip"
- uses: ./.github/actions/setup-system
- uses: actions/download-artifact@v4
with:
name: cibw-sdist
Expand All @@ -62,16 +63,17 @@ jobs:
with:
python-version: "3.12"
cache: "pip"
- uses: ./.github/actions/setup-system
- name: Install pandoc&graphviz
run: sudo apt-get install pandoc graphviz
- name: Install silx
run: pip install .[full,test,doc]
run: pip install .[full,test,doc] siphash24
- name: Build doc
env:
QT_QPA_PLATFORM: "offscreen"
run: |
export SILX_VERSION="$(python -c 'import silx; print(silx.strictversion)')"
sphinx-build doc/source/ "silx-${SILX_VERSION}_documentation/"
sphinx-build --fail-on-warning doc/source/ "silx-${SILX_VERSION}_documentation/"
zip -r "silx-${SILX_VERSION}_documentation.zip" "silx-${SILX_VERSION}_documentation/"
- uses: actions/upload-artifact@v4
with:
Expand Down Expand Up @@ -132,19 +134,14 @@ jobs:
include:
- os: ubuntu-20.04
cibw_archs: "auto64"
with_sse2: true
- os: ubuntu-20.04
cibw_archs: "aarch64"
with_sse2: false
- os: ubuntu-20.04
cibw_archs: "ppc64le"
with_sse2: false
- os: windows-2019
cibw_archs: "auto64"
with_sse2: true
- os: macos-12
cibw_archs: "universal2"
with_sse2: true

steps:
- uses: actions/checkout@v4
Expand All @@ -167,11 +164,15 @@ jobs:

CIBW_BUILD_VERBOSITY: 1
CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-*
CIBW_MANYLINUX_X86_64_IMAGE: manylinux_2_28
CIBW_MANYLINUX_AARCH64_IMAGE: manylinux_2_28
CIBW_MANYLINUX_PPC64LE_IMAGE: manylinux_2_28
# Do not build for pypy and muslinux
CIBW_SKIP: pp* *-musllinux_*
CIBW_ARCHS: ${{ matrix.cibw_archs }}

# Install test dependencies
CIBW_BEFORE_TEST_LINUX: yum install -y mesa-libEGL mesa-libGL libxkbcommon-x11 libxkbcommon xcb-util-image xcb-util-keysyms libXrandr xcb-util-renderutil libXcursor libxcb
CIBW_TEST_EXTRAS: "full,test"
CIBW_TEST_COMMAND: python -c "import silx.test, sys; sys.exit(silx.test.run_tests(verbosity=3))"
# Skip tests for emulated architectures and arm64 macos
Expand Down
6 changes: 3 additions & 3 deletions doc/source/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -144,9 +144,9 @@ The mandatory dependencies are:

The GUI widgets depend on the following extra packages:

* A Qt binding: either `PyQt5 <https://riverbankcomputing.com/software/pyqt/intro>`_ (>= 5.9),
`PySide6 <https://pypi.org/project/PySide6/>`_ (>= 6.4) or
`PyQt6 <https://pypi.org/project/PyQt6/>`_ (>= 6.3)
* A Qt binding: either `PySide6 <https://pypi.org/project/PySide6/>`_ (>= 6.4),
`PyQt6 <https://pypi.org/project/PyQt6/>`_ (>= 6.3) or
`PyQt5 <https://riverbankcomputing.com/software/pyqt/intro>`_ (>= 5.9)
* `matplotlib <http://matplotlib.org/>`_
* `PyOpenGL <http://pyopengl.sourceforge.net/>`_
* `qtconsole <https://pypi.org/project/qtconsole>`_
Expand Down
4 changes: 2 additions & 2 deletions doc/source/license.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ Note:

silx uses the Qt library for its graphical user interfaces.
A word of caution is to be provided.
If users develop and distribute software using modules accessing Qt by means of Riverbank Computing Qt bindings PyQt4 or PyQt5, those users will be conditioned by the license of their PyQt4/5 software (GPL or commercial).
If the end user does not own a commercial license of PyQt4 or PyQt5 and wishes to be free of any distribution condition, (s)he should be able to use PySide6 because it uses the LGPL license.
If users develop and distribute software using modules accessing Qt by means of Riverbank Computing Qt bindings PyQt6 or PyQt5, those users will be conditioned by the license of their PyQt6/5 software (GPL or commercial).
If the end user does not own a commercial license of PyQt6 or PyQt5 and wishes to be free of any distribution condition, (s)he should be able to use PySide6 because it uses the LGPL license.

The following list provides the copyright and license of the different source files of the project:

Expand Down
6 changes: 3 additions & 3 deletions doc/source/modules/gui/plot/getting_started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ Compatibility with IPython
++++++++++++++++++++++++++

silx widgets require Qt to be initialized.
If Qt is not yet loaded, silx tries to load PyQt5 first before trying other supported bindings.
If Qt is not yet loaded, silx tries to load PySide6 first before trying other supported bindings.

With versions of IPython lower than 3.0 (e.g., on Debian 8), there is an incompatibility between
the way silx loads Qt and the way IPython is doing it through the ``--gui`` option,
Expand Down Expand Up @@ -87,13 +87,13 @@ A Qt GUI script must have a QApplication initialised before creating widgets:
[...]
qapp.exec()

Unless a Qt binding has already been loaded, :mod:`silx.gui.qt` uses one of the supported Qt bindings (PyQt5, PySide6, PyQt6).
Unless a Qt binding has already been loaded, :mod:`silx.gui.qt` uses one of the supported Qt bindings (PySide6, PyQt6, PyQt5).
If you prefer to choose the Qt binding yourself, import it before importing
a module from :mod:`silx.gui`:

.. code-block:: python

import PyQt5.QtCore # Importing PyQt5 will force silx to use it
import PyQt6.QtCore # Importing PyQt6 will force silx to use it
from silx.gui import qt


Expand Down
7 changes: 2 additions & 5 deletions package/windows/pyinstaller.spec
Original file line number Diff line number Diff line change
Expand Up @@ -108,20 +108,17 @@ silx_coll = COLLECT(

# Generate license file from current Python env
def create_license_file(filename: str):
import PyQt5.QtCore
import PySide6.QtCore

with open(filename, "w") as f:
f.write(
f"""
This is free software.

This distribution of silx is provided under the
GNU General Public License v3 (https://www.gnu.org/licenses/gpl-3.0.en.html) since it includes PyQt5.

It includes mainy software packages with different licenses:

- Python ({sys.version}): PSF license, https://www.python.org/
- Qt ({PyQt5.QtCore.qVersion()}): GNU Lesser General Public License v3, https://www.qt.io/
- Qt ({PySide6.QtCore.qVersion()}): GNU Lesser General Public License v3, https://www.qt.io/
"""
)

Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,4 @@ scipy # For silx.math.fit demo, silx.image.sift demo, silx.i
pooch # For scipy.datasets.ascent
Pillow # For silx.opencl.image.test
pint # For silx.io.dictdump
PyQt5 # PySide6, PyQt6>=6.3 # For silx.gui
PySide6 >= 6.4 # PyQt6, PyQt5 # For silx.gui
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ def get_project_configuration():
"matplotlib>=3.1.0",
"PyOpenGL",
"python-dateutil",
"PyQt5",
"PySide6>=6.4",
# extra
"hdf5plugin",
"scipy",
Expand Down
4 changes: 2 additions & 2 deletions src/silx/gui/qt/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@
# ###########################################################################*/
"""Common wrapper over Python Qt bindings:

- `PyQt5 <http://pyqt.sourceforge.net/Docs/PyQt5/>`_
- `PySide6 <https://pypi.org/project/PySide6/>`_
- `PyQt6 <https://pypi.org/project/PyQt6/>`_
- `PyQt5 <http://pyqt.sourceforge.net/Docs/PyQt5/>`_

If a Qt binding is already loaded, it will be used.
If the `QT_API` environment variable is set to one of the supported Qt bindings
(case insensitive), this binding is loaded if available, otherwise the
different Qt bindings are tried in this order: PyQt5, PySide6, PyQt6.
different Qt bindings are tried in this order: PySide6, PyQt6, PyQt5.

The name of the loaded Qt binding is stored in the BINDING variable.

Expand Down
8 changes: 4 additions & 4 deletions src/silx/gui/qt/_qt.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@


BINDING = None
"""The name of the Qt binding in use: PyQt5, PySide6, PyQt6."""
"""The name of the Qt binding in use: PySide6, PyQt6, PyQt5."""

QtBinding = None # noqa
"""The Qt binding module in use: PyQt5, PySide6, PyQt6."""
"""The Qt binding module in use: PySide6, PyQt6, PyQt5."""

HAS_SVG = False
"""True if Qt provides support for Scalable Vector Graphics (QtSVG)."""
Expand All @@ -64,7 +64,7 @@ def _select_binding() -> str:
:raises ImportError:
:returns: Loaded binding
"""
bindings = "PyQt5", "PySide6", "PyQt6"
bindings = "PySide6", "PyQt6", "PyQt5"

envvar = os.environ.get("QT_API", "").lower()

Expand Down Expand Up @@ -103,7 +103,7 @@ def _select_binding() -> str:
else:
return binding

raise ImportError("No Qt wrapper found. Install PyQt5, PySide6, PyQt6.")
raise ImportError("No Qt wrapper found. Install PySide6, PyQt6, PyQt5.")


BINDING = _select_binding()
Expand Down
1 change: 1 addition & 0 deletions src/silx/test/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ def run_tests(
"-Wignore:tostring() is deprecated. Use tobytes() instead.:DeprecationWarning:OpenGL.GL.VERSION.GL_2_0",
"-Wignore:Jupyter is migrating its paths to use standard platformdirs:DeprecationWarning",
"-Wignore:Unable to import recommended hash 'siphash24.siphash13', falling back to 'hashlib.sha256'. Run 'python3 -m pip install siphash24' to install the recommended hash.:UserWarning:pytools.persistent_dict",
"-Wignore:Non-empty compiler output encountered. Set the environment variable PYOPENCL_COMPILER_OUTPUT=1 to see more.:UserWarning",
# Remove __array__ ignore once h5py v3.12 is released
"-Wignore:__array__ implementation doesn't accept a copy keyword, so passing copy=False failed. __array__ must implement 'dtype' and 'copy' keyword arguments.:DeprecationWarning",
] + list(args)
Expand Down
Loading