Skip to content

Commit

Permalink
Merge pull request #1018 from astrofrog/use-qtpy
Browse files Browse the repository at this point in the history
Use of QtPy instead of qt-helpers
  • Loading branch information
astrofrog committed Aug 7, 2016
2 parents 4029f01 + ec0972d commit ac50652
Show file tree
Hide file tree
Showing 93 changed files with 573 additions and 1,053 deletions.
33 changes: 20 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ env:
- PYTHON_VERSION=2.7 ASTROPY_VERSION=1.0
- PYTHON_VERSION=3.4 ASTROPY_VERSION=1.0
global:
- PYTEST_ARGS="--cov glue"
- CONDA_CHANNELS='conda-forge spyder-ide'
- ASTROPY_VERSION=stable
- PYTEST_ARGS="--cov glue -vs"
- MATPLOTLIB_VERSION=1.5.0
- NUMPY_VERSION=1.10
- ASTROPY_VERSION=stable
Expand All @@ -28,7 +30,7 @@ env:
- QT_PKG=pyqt
- SETUP_XVFB=True
# Note that we need to specify requests 2.9 because of a bug in the version check in linkchecker
- CONDA_DEPENDENCIES="pip dill ipython matplotlib scipy cython h5py pygments pyzmq scikit-image pandas sphinx=1.2.3 xlrd pillow pytest mock coverage pyyaml requests=2.9 sphinx_rtd_theme"
- CONDA_DEPENDENCIES="nomkl pip dill ipython matplotlib scipy cython h5py pygments pyzmq scikit-image pandas sphinx=1.2.3 xlrd pillow pytest mock coverage pyyaml requests=2.9 sphinx_rtd_theme qtpy"
- PIP_DEPENDENCIES="pytest-cov coveralls pyavm astrodendro awscli ginga plotly"
- secure: NvQVc3XmmjXNVKrmaD31IgltsOImlnt3frAl4wU0pM223iejr7V57hz/V5Isx6sTANWEiRBMG27v2T8e5IiB7DQTxFUleZk3DWXQV1grw/GarEGUawXAgwDWpF0AE/7BRVJYqo2Elgaqf28+Jkun8ewvfPCiEROD2jWEpnZj+IQ=
- secure: "SU9BYH8d9eNigypG3lC83s0NY6Mq9AHGKXyEGeXDtz1npJIC1KHdzPMP1v1K3dzCgl1p6ReMXPjZMCENyfNkad/xvzTzGk0Nu/4BjihrUPV6+ratVeLpv0JLm8ikh8q+sZURkdtzUOlds+Hfn5ku4LdpT87tcKHY9TINAGA34ZM="
Expand Down Expand Up @@ -68,7 +70,7 @@ matrix:
env:
- PYTHON_VERSION=2.7
- PYTEST_ARGS="--cov glue"
- CONDA_DEPENDENCIES="pytz pyparsing cycler python-dateutil freetype libpng sip qt pip setuptools=7.0 pandas mock pbr six funcsigs matplotlib"
- CONDA_DEPENDENCIES="pytz pyparsing cycler python-dateutil freetype libpng sip qt pip setuptools=7.0 pandas mock pbr six funcsigs matplotlib qtpy"
- CONDA_DEPENDENCIES_FLAGS='--no-deps'
- PIP_DEPENDENCIES="pytest-cov coveralls"

Expand All @@ -84,13 +86,16 @@ matrix:
# Test with older package versions:

- os: linux
env: PYTHON_VERSION=2.7 MATPLOTLIB_VERSION=1.3 ASTROPY_VERSION=0.3 NUMPY_VERSION=1.8
env:
- PYTHON_VERSION=2.7 MATPLOTLIB_VERSION=1.3 ASTROPY_VERSION=0.3 NUMPY_VERSION=1.8

- os: linux
env: PYTHON_VERSION=2.7 MATPLOTLIB_VERSION=1.4 ASTROPY_VERSION=0.4 NUMPY_VERSION=1.9 IPYTHON_VERSION=1.1
env:
- PYTHON_VERSION=2.7 MATPLOTLIB_VERSION=1.4 ASTROPY_VERSION=0.4 NUMPY_VERSION=1.9 IPYTHON_VERSION=1.1

- os: linux
env: PYTHON_VERSION=2.7 MATPLOTLIB_VERSION=1.4 ASTROPY_VERSION=0.4 NUMPY_VERSION=1.9 IPYTHON_VERSION=0.13
env:
- PYTHON_VERSION=2.7 MATPLOTLIB_VERSION=1.4 ASTROPY_VERSION=0.4 NUMPY_VERSION=1.9 IPYTHON_VERSION=0.13

# Test with PySide, but due to segmentation faults, mark as an
# allowed failure.
Expand All @@ -115,11 +120,12 @@ matrix:

before_install:

# The PyQt5 package is in the spyder-ide channel
- if [[ $QT_PKG == pyqt5 ]]; then export CONDA_CHANNELS="astropy-ci-extras spyder-ide"; fi

# Prepare dependency list
- if [[ $QT_PKG != False ]]; then export CONDA_DEPENDENCIES="$QT_PKG "$CONDA_DEPENDENCIES; fi
# Prepare dependency list. Note that in future, PyQt5 will be the pyqt conda
# package with a version of 5.x rather than a pyqt5 package, so we explicitly
# request pyqt=4 for PyQt4.
- if [[ $QT_PKG == pyside ]]; then export CONDA_DEPENDENCIES="pyside "$CONDA_DEPENDENCIES; fi
- if [[ $QT_PKG == pyqt ]]; then export CONDA_DEPENDENCIES="pyqt=4 "$CONDA_DEPENDENCIES; fi
- if [[ $QT_PKG == pyqt5 ]]; then export CONDA_DEPENDENCIES="pyqt5 "$CONDA_DEPENDENCIES; fi

# Special cases depending on IPython version
- if [[ $IPYTHON_VERSION == 4 ]]; then export CONDA_DEPENDENCIES="traitlets=4.1.0 qtconsole ipykernel "$CONDA_DEPENDENCIES; fi
Expand All @@ -145,8 +151,8 @@ install:
- LC_ALL=C

# Uninstall PyQt if we are using PySide or PyQt5
- if [ $QT_PKG == pyside ]; then conda remove pyqt sip || true; fi
- if [ $QT_PKG == pyqt5 ]; then conda remove pyqt qt || true; fi
- if [ $QT_PKG == pyside ]; then conda remove --no-pin --force pyqt sip || true; fi
- if [ $QT_PKG == pyqt5 ]; then conda remove --no-pin --force pyqt qt || true; fi

- if [[ $QT_PKG == pyqt5 ]]; then
export QT_QPA_PLATFORM_PLUGIN_PATH=$HOME/miniconda/envs/test/lib/qt5/plugins/platforms;
Expand All @@ -156,6 +162,7 @@ install:
# Uninstall any version of Qt if QT_PKG is False, and remove all qt
# sub-directories
- if [[ $QT_PKG == False ]]; then
conda remove --no-pin --force qtpy || true;
conda remove --no-pin --force pyqt || true;
conda remove --no-pin --force pyside || true;
conda remove --no-pin --force pyqt5 || true;
Expand Down
5 changes: 5 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ v0.9.0 (unreleased)
``remove_data``, and added a new ``ComponentIDComboHelper.set_multiple_data``
method. [#1060]

* Make use of the QtPy package to deal with differences between PyQt4, PyQt5,
and PySide, instead of the custom qt-helpers package. The
``glue.external.qt`` package is now deprecated. The ``get_qapp`` and
``load_ui`` functions are now available in ``glue.utils.qt``.

v0.8.3 (unreleased)
-------------------

Expand Down
3 changes: 2 additions & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ environment:
PYTHON_ARCH: "64" # needs to be set for CMD_IN_ENV to succeed. If a mix
# of 32 bit and 64 bit builds are needed, move this
# to the matrix section.
CONDA_DEPENDENCIES: "scipy cython pyqt matplotlib h5py pygments pyzmq scikit-image pandas sphinx xlrd pillow pytest mock coverage ipython ipykernel qtconsole traitlets=4.1.0"
CONDA_CHANNELS: "conda-forge"
CONDA_DEPENDENCIES: "scipy cython pyqt matplotlib h5py pygments pyzmq scikit-image pandas sphinx xlrd pillow pytest mock coverage ipython ipykernel qtconsole traitlets=4.1.0 qtpy"
PIP_DEPENDENCIES: "plotly"

matrix:
Expand Down
15 changes: 5 additions & 10 deletions doc/developer_guide/organization.rst
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,11 @@ top-level sub-packages (starting with some of the easy ones):
This is a sub-package that you should never have to edit directly. It contains
files and modules edited in other repositories that have been bundled with
Glue. If you do need to make any changes to them, you should first edit those
other repositories, and then port over the changes to Glue. The most notable
example is ``glue.external.qt``, which is a bundled version of the `qt-helpers
<https://github.com/glue-viz/qt-helpers>`_. This sub-package provides a common
interface for PyQt4, PyQt5, and PySide. See :ref:`qthelpers` for more
details. Another example is ``glue.external.echo``, which is a bundled version
of the `echo <https://github.com/glue-viz/echo>`_ library, which makes it easy
to attach callback functions to class properties. In general, it's useful to
know these bundled modules are available, but you will likely not need to edit
them.

other repositories, and then port over the changes to Glue. One of the main
examples is ``glue.external.echo``, which is a bundled version of the `echo
<https://github.com/glue-viz/echo>`_ library, which makes it easy to attach
callback functions to class properties. In general, it's useful to know these
bundled modules are available, but you will likely not need to edit them.

``glue.utils``
^^^^^^^^^^^^^^
Expand Down
21 changes: 11 additions & 10 deletions doc/developer_guide/qt_development.rst
Original file line number Diff line number Diff line change
@@ -1,23 +1,24 @@
Qt development in Glue
======================

.. _qthelpers:
.. _qtpy:

Using qt-helpers
----------------
Using QtPy
----------

If you are interested in working on some of the Qt-specific code, it's
important that you don't import any code directly from PyQt4, PyQt5, or PySide.
Since we want to maintain backward-compatibility with all of these, you should
always import from ``glue.external.qt`` as if this was one of the Python Qt
packages. For instance, instead of::
always use the `QtPy <https://pypi.python.org/pypi/QtPy>`__ package. The way to
use this package is to import from the ``qtpy`` module as if it was the
``PyQt5`` module, and QtPy will automatically translate this into the
appropriate imports for PySide or PyQt4 if needed. For instance, instead of::

from PyQt4 import QtGui
from PyQt4 import QtCore

you should do::

from glue.external.qt import QtGui
from qtpy import QtCore

Note that for now, if the PyQt4 and PyQt5 import paths would be different, you
should use the PyQt4 one, and we have provided patches in ``glue.external.qt``
to make PyQt5 backward-compatible.
Note that if the PyQt4 and PyQt5 import paths would be different, you should
use the PyQt5 one.
4 changes: 2 additions & 2 deletions doc/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@ Glue has the following required dependencies:
* `Numpy <http://www.numpy.org>`_
* `Matplotlib <http://www.matplotlib.org>`_
* `Pandas <http://pandas.pydata.org/>`_
* Either `PyQt4`_ or `PySide`_ (or `PyQt5 <https://riverbankcomputing.com/software/pyqt/download5>`_, but support is still
experimental)
* Either `PySide`_, `PyQt4`_, or `PyQt5 <https://riverbankcomputing.com/software/pyqt/download5>`_
* `QtPy <https://pypi.python.org/pypi/QtPy/>`__ 1.1 or higher - this is an abstraction layer for the Python Qt packages

And the following optional dependencies are also highly recommended:

Expand Down
1 change: 1 addition & 0 deletions glue/_deps.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ def version(self):
)

required = (
Dependency('qtpy', 'Required'),
Dependency('setuptools', 'Required'),
Dependency('numpy', 'Required', min_version='1.4'),
Dependency('matplotlib', 'Required for plotting', min_version='1.1'),
Expand Down
10 changes: 8 additions & 2 deletions glue/_mpl_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ def find_spec(self, name, import_path, target_module=None):

def set_mpl_backend():

try:
from qtpy import PYQT5
except:
# If Qt isn't available, we don't have to worry about
# setting the backend
return

from matplotlib import rcParams, rcdefaults

# standardize mpl setup
rcdefaults()

from glue.external.qt import is_pyqt5
if is_pyqt5():
if PYQT5:
rcParams['backend'] = 'Qt5Agg'
else:
rcParams['backend'] = 'Qt4Agg'
Expand Down
6 changes: 3 additions & 3 deletions glue/app/qt/actions.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from __future__ import absolute_import, division, print_function

from glue.external.qt import QtGui
from qtpy import QtWidgets
from glue.icons.qt import get_icon
from glue.utils.qt.helpers import CUSTOM_QWIDGETS


class GlueActionButton(QtGui.QPushButton):
class GlueActionButton(QtWidgets.QPushButton):

def set_action(self, action, text=True):
self._text = text
Expand All @@ -27,7 +27,7 @@ def _sync_to_action(self):

def action(name, parent, tip='', icon=None, shortcut=None):
""" Factory for making a new action """
a = QtGui.QAction(name, parent)
a = QtWidgets.QAction(name, parent)
a.setToolTip(tip)
if icon:
a.setIcon(get_icon(icon))
Expand Down

0 comments on commit ac50652

Please sign in to comment.