aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/ipython/py3/IPython/external/qt_for_kernel.py
blob: d2e7bd99f01252473e44c9000bce781411a2ac31 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
""" Import Qt in a manner suitable for an IPython kernel.

This is the import used for the `gui=qt` or `matplotlib=qt` initialization.

Import Priority:

if Qt has been imported anywhere else:
   use that

if matplotlib has been imported and doesn't support v2 (<= 1.0.1):
    use PyQt4 @v1

Next, ask QT_API env variable

if QT_API not set:
    ask matplotlib what it's using. If Qt4Agg or Qt5Agg, then use the
        version matplotlib is configured with

    else: (matplotlib said nothing)
        # this is the default path - nobody told us anything
        try in this order:
            PyQt default version, PySide, PyQt5
else:
    use what QT_API says

"""
# NOTE: This is no longer an external, third-party module, and should be
# considered part of IPython. For compatibility however, it is being kept in
# IPython/external.

import os
import sys

from IPython.utils.version import check_version
from IPython.external.qt_loaders import (
    load_qt,
    loaded_api,
    enum_factory,
    # QT6
    QT_API_PYQT6,
    QT_API_PYSIDE6,
    # QT5
    QT_API_PYQT5,
    QT_API_PYSIDE2,
    # QT4
    QT_API_PYQTv1,
    QT_API_PYQT,
    QT_API_PYSIDE,
    # default
    QT_API_PYQT_DEFAULT,
)

_qt_apis = (
    # QT6
    QT_API_PYQT6,
    QT_API_PYSIDE6,
    # QT5
    QT_API_PYQT5,
    QT_API_PYSIDE2,
    # QT4
    QT_API_PYQTv1,
    QT_API_PYQT,
    QT_API_PYSIDE,
    # default
    QT_API_PYQT_DEFAULT,
)


def matplotlib_options(mpl):
    """Constraints placed on an imported matplotlib."""
    if mpl is None:
        return
    backend = mpl.rcParams.get('backend', None)
    if backend == 'Qt4Agg':
        mpqt = mpl.rcParams.get('backend.qt4', None)
        if mpqt is None:
            return None
        if mpqt.lower() == 'pyside':
            return [QT_API_PYSIDE]
        elif mpqt.lower() == 'pyqt4':
            return [QT_API_PYQT_DEFAULT]
        elif mpqt.lower() == 'pyqt4v2':
            return [QT_API_PYQT]
        raise ImportError("unhandled value for backend.qt4 from matplotlib: %r" %
                          mpqt)
    elif backend == 'Qt5Agg':
        mpqt = mpl.rcParams.get('backend.qt5', None)
        if mpqt is None:
            return None
        if mpqt.lower() == 'pyqt5':
            return [QT_API_PYQT5]
        raise ImportError("unhandled value for backend.qt5 from matplotlib: %r" %
                          mpqt)

def get_options():
    """Return a list of acceptable QT APIs, in decreasing order of preference."""
    #already imported Qt somewhere. Use that
    loaded = loaded_api()
    if loaded is not None:
        return [loaded]

    mpl = sys.modules.get('matplotlib', None)

    if mpl is not None and not check_version(mpl.__version__, '1.0.2'):
        #1.0.1 only supports PyQt4 v1
        return [QT_API_PYQT_DEFAULT]

    qt_api = os.environ.get('QT_API', None)
    if qt_api is None:
        #no ETS variable. Ask mpl, then use default fallback path
        return matplotlib_options(mpl) or [
            QT_API_PYQT_DEFAULT,
            QT_API_PYQT6,
            QT_API_PYSIDE6,
            QT_API_PYQT5,
            QT_API_PYSIDE2,
            QT_API_PYQT,
            QT_API_PYSIDE,
        ]
    elif qt_api not in _qt_apis:
        raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
                           (qt_api, ', '.join(_qt_apis)))
    else:
        return [qt_api]


api_opts = get_options()
QtCore, QtGui, QtSvg, QT_API = load_qt(api_opts)
enum_helper = enum_factory(QT_API, QtCore)