##// END OF EJS Templates
Remove direct support for Qt4...
Emilio Graff -
Show More
@@ -493,8 +493,10 b' Currently the magic system has the following functions:""",'
493 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
493 are supported: wxPython, PyQt4, PyGTK, Tk and Cocoa (OSX)::
494
494
495 %gui wx # enable wxPython event loop integration
495 %gui wx # enable wxPython event loop integration
496 %gui qt4|qt # enable PyQt4 event loop integration
496 %gui qt # enable PyQt/PySide event loop integration
497 %gui qt5 # enable PyQt5 event loop integration
497 # with the latest version available.
498 %gui qt6 # enable PyQt6/PySide6 event loop integration
499 %gui qt5 # enable PyQt5/PySide2 event loop integration
498 %gui gtk # enable PyGTK event loop integration
500 %gui gtk # enable PyGTK event loop integration
499 %gui gtk3 # enable Gtk3 event loop integration
501 %gui gtk3 # enable Gtk3 event loop integration
500 %gui gtk4 # enable Gtk4 event loop integration
502 %gui gtk4 # enable Gtk4 event loop integration
@@ -45,7 +45,6 b' from IPython.external.qt_loaders import ('
45 QT_API_PYQT5,
45 QT_API_PYQT5,
46 QT_API_PYSIDE2,
46 QT_API_PYSIDE2,
47 # QT4
47 # QT4
48 QT_API_PYQTv1,
49 QT_API_PYQT,
48 QT_API_PYQT,
50 QT_API_PYSIDE,
49 QT_API_PYSIDE,
51 # default
50 # default
@@ -59,10 +58,6 b' _qt_apis = ('
59 # QT5
58 # QT5
60 QT_API_PYQT5,
59 QT_API_PYQT5,
61 QT_API_PYSIDE2,
60 QT_API_PYSIDE2,
62 # QT4
63 QT_API_PYQTv1,
64 QT_API_PYQT,
65 QT_API_PYSIDE,
66 # default
61 # default
67 QT_API_PYQT_DEFAULT,
62 QT_API_PYQT_DEFAULT,
68 )
63 )
@@ -116,8 +111,6 b' def get_options():'
116 QT_API_PYSIDE6,
111 QT_API_PYSIDE6,
117 QT_API_PYQT5,
112 QT_API_PYQT5,
118 QT_API_PYSIDE2,
113 QT_API_PYSIDE2,
119 QT_API_PYQT,
120 QT_API_PYSIDE,
121 ]
114 ]
122 elif qt_api not in _qt_apis:
115 elif qt_api not in _qt_apis:
123 raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
116 raise RuntimeError("Invalid Qt API %r, valid values are: %r" %
@@ -24,6 +24,7 b" QT_API_PYQT5 = 'pyqt5'"
24 QT_API_PYSIDE2 = 'pyside2'
24 QT_API_PYSIDE2 = 'pyside2'
25
25
26 # Qt4
26 # Qt4
27 # NOTE: Here for legacy matplotlib compatibility, but not really supported on the IPython side.
27 QT_API_PYQT = "pyqt" # Force version 2
28 QT_API_PYQT = "pyqt" # Force version 2
28 QT_API_PYQTv1 = "pyqtv1" # Force version 2
29 QT_API_PYQTv1 = "pyqtv1" # Force version 2
29 QT_API_PYSIDE = "pyside"
30 QT_API_PYSIDE = "pyside"
@@ -374,20 +375,16 b' def load_qt(api_options):'
374 PySide6 is available, and only one is imported per session.
375 PySide6 is available, and only one is imported per session.
375
376
376 Currently-imported Qt library: %r
377 Currently-imported Qt library: %r
377 PyQt4 available (requires QtCore, QtGui, QtSvg): %s
378 PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
378 PyQt5 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
379 PyQt6 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
379 PyQt6 available (requires QtCore, QtGui, QtSvg, QtWidgets): %s
380 PySide >= 1.0.3 installed: %s
381 PySide2 installed: %s
380 PySide2 installed: %s
382 PySide6 installed: %s
381 PySide6 installed: %s
383 Tried to load: %r
382 Tried to load: %r
384 """
383 """
385 % (
384 % (
386 loaded_api(),
385 loaded_api(),
387 has_binding(QT_API_PYQT),
388 has_binding(QT_API_PYQT5),
386 has_binding(QT_API_PYQT5),
389 has_binding(QT_API_PYQT6),
387 has_binding(QT_API_PYQT6),
390 has_binding(QT_API_PYSIDE),
391 has_binding(QT_API_PYSIDE2),
388 has_binding(QT_API_PYSIDE2),
392 has_binding(QT_API_PYSIDE6),
389 has_binding(QT_API_PYSIDE6),
393 api_options,
390 api_options,
@@ -106,11 +106,11 b' def start_event_loop_wx(app=None):'
106 app._in_event_loop = True
106 app._in_event_loop = True
107
107
108 #-----------------------------------------------------------------------------
108 #-----------------------------------------------------------------------------
109 # qt4
109 # Qt
110 #-----------------------------------------------------------------------------
110 #-----------------------------------------------------------------------------
111
111
112 def get_app_qt4(*args, **kwargs):
112 def get_app_qt(*args, **kwargs):
113 """Create a new qt4 app or return an existing one."""
113 """Create a new Qt app or return an existing one."""
114 from IPython.external.qt_for_kernel import QtGui
114 from IPython.external.qt_for_kernel import QtGui
115 app = QtGui.QApplication.instance()
115 app = QtGui.QApplication.instance()
116 if app is None:
116 if app is None:
@@ -119,8 +119,8 b' def get_app_qt4(*args, **kwargs):'
119 app = QtGui.QApplication(*args, **kwargs)
119 app = QtGui.QApplication(*args, **kwargs)
120 return app
120 return app
121
121
122 def is_event_loop_running_qt4(app=None):
122 def is_event_loop_running_qt(app=None):
123 """Is the qt4 event loop running."""
123 """Is the qt event loop running."""
124 # New way: check attribute on shell instance
124 # New way: check attribute on shell instance
125 ip = get_ipython()
125 ip = get_ipython()
126 if ip is not None:
126 if ip is not None:
@@ -128,18 +128,18 b' def is_event_loop_running_qt4(app=None):'
128
128
129 # Old way: check attribute on QApplication singleton
129 # Old way: check attribute on QApplication singleton
130 if app is None:
130 if app is None:
131 app = get_app_qt4([''])
131 app = get_app_qt([''])
132 if hasattr(app, '_in_event_loop'):
132 if hasattr(app, '_in_event_loop'):
133 return app._in_event_loop
133 return app._in_event_loop
134 else:
134 else:
135 # Does qt4 provide a other way to detect this?
135 # Does qt provide a other way to detect this?
136 return False
136 return False
137
137
138 def start_event_loop_qt4(app=None):
138 def start_event_loop_qt(app=None):
139 """Start the qt4 event loop in a consistent manner."""
139 """Start the qt event loop in a consistent manner."""
140 if app is None:
140 if app is None:
141 app = get_app_qt4([''])
141 app = get_app_qt([''])
142 if not is_event_loop_running_qt4(app):
142 if not is_event_loop_running_qt(app):
143 app._in_event_loop = True
143 app._in_event_loop = True
144 app.exec_()
144 app.exec_()
145 app._in_event_loop = False
145 app._in_event_loop = False
@@ -8,7 +8,6 b' aliases = {'
8
8
9 backends = [
9 backends = [
10 "qt",
10 "qt",
11 "qt4",
12 "qt5",
11 "qt5",
13 "qt6",
12 "qt6",
14 "gtk",
13 "gtk",
@@ -80,21 +79,7 b' def set_qt_api(gui):'
80 f'environment variable is set to "{qt_api}"'
79 f'environment variable is set to "{qt_api}"'
81 )
80 )
82 else:
81 else:
83 # NOTE: 'qt4' is not selectable because it's set as an alias for 'qt'; see `aliases` above.
82 if gui == "qt5":
84 if gui == "qt4":
85 try:
86 import PyQt # noqa
87
88 os.environ["QT_API"] = "pyqt"
89 except ImportError:
90 try:
91 import PySide # noqa
92
93 os.environ["QT_API"] = "pyside"
94 except ImportError:
95 # Neither implementation installed; set it to something so IPython gives an error
96 os.environ["QT_API"] = "pyqt"
97 elif gui == "qt5":
98 try:
83 try:
99 import PyQt5 # noqa
84 import PyQt5 # noqa
100
85
@@ -124,7 +109,7 b' def set_qt_api(gui):'
124 del os.environ["QT_API"]
109 del os.environ["QT_API"]
125 else:
110 else:
126 raise ValueError(
111 raise ValueError(
127 f'Unrecognized Qt version: {gui}. Should be "qt4", "qt5", "qt6", or "qt".'
112 f'Unrecognized Qt version: {gui}. Should be "qt5", "qt6", or "qt".'
128 )
113 )
129
114
130
115
@@ -12,7 +12,7 b' guis_avail = []'
12 def _get_qt_vers():
12 def _get_qt_vers():
13 """If any version of Qt is available, this will populate `guis_avail` with 'qt' and 'qtx'. Due
13 """If any version of Qt is available, this will populate `guis_avail` with 'qt' and 'qtx'. Due
14 to the import mechanism, we can't import multiple versions of Qt in one session."""
14 to the import mechanism, we can't import multiple versions of Qt in one session."""
15 for gui in ["qt", "qt6", "qt5", "qt4"]:
15 for gui in ["qt", "qt6", "qt5"]:
16 print(f"Trying {gui}")
16 print(f"Trying {gui}")
17 try:
17 try:
18 set_qt_api(gui)
18 set_qt_api(gui)
@@ -39,7 +39,7 b' def test_inputhook_qt():'
39 get_inputhook_name_and_func(gui)
39 get_inputhook_name_and_func(gui)
40
40
41 # ...and now we're stuck with this version of Qt for good; can't switch.
41 # ...and now we're stuck with this version of Qt for good; can't switch.
42 for not_gui in ["qt6", "qt5", "qt4"]:
42 for not_gui in ["qt6", "qt5"]:
43 if not_gui not in guis_avail:
43 if not_gui not in guis_avail:
44 break
44 break
45
45
@@ -7,7 +7,7 b' loop, so you can use both a GUI and an interactive prompt together. IPython'
7 supports a number of common GUI toolkits, but from IPython 3.0, it is possible
7 supports a number of common GUI toolkits, but from IPython 3.0, it is possible
8 to integrate other event loops without modifying IPython itself.
8 to integrate other event loops without modifying IPython itself.
9
9
10 Supported event loops include ``qt4``, ``qt5``, ``gtk2``, ``gtk3``, ``gtk4``,
10 Supported event loops include ``qt5``, ``qt6``, ``gtk2``, ``gtk3``, ``gtk4``,
11 ``wx``, ``osx`` and ``tk``. Make sure the event loop you specify matches the
11 ``wx``, ``osx`` and ``tk``. Make sure the event loop you specify matches the
12 GUI toolkit used by your own code.
12 GUI toolkit used by your own code.
13
13
@@ -44,7 +44,7 b' the command-line by passing the full class name and a corresponding value; type'
44 <...snip...>
44 <...snip...>
45 --matplotlib=<CaselessStrEnum> (InteractiveShellApp.matplotlib)
45 --matplotlib=<CaselessStrEnum> (InteractiveShellApp.matplotlib)
46 Default: None
46 Default: None
47 Choices: ['auto', 'gtk', 'gtk3', 'gtk4', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt4', 'qt5', 'tk', 'wx']
47 Choices: ['auto', 'gtk', 'gtk3', 'gtk4', 'inline', 'nbagg', 'notebook', 'osx', 'qt', 'qt5', 'qt6', 'tk', 'wx']
48 Configure matplotlib for interactive use with the default matplotlib
48 Configure matplotlib for interactive use with the default matplotlib
49 backend.
49 backend.
50 <...snip...>
50 <...snip...>
@@ -892,7 +892,7 b' GUI event loop support'
892 ======================
892 ======================
893
893
894 IPython has excellent support for working interactively with Graphical User
894 IPython has excellent support for working interactively with Graphical User
895 Interface (GUI) toolkits, such as wxPython, PyQt4/PySide, PyGTK and Tk. This is
895 Interface (GUI) toolkits, such as wxPython, PyQt/PySide, PyGTK and Tk. This is
896 implemented by running the toolkit's event loop while IPython is waiting for
896 implemented by running the toolkit's event loop while IPython is waiting for
897 input.
897 input.
898
898
@@ -902,7 +902,7 b' For users, enabling GUI event loop integration is simple. You simple use the'
902 %gui [GUINAME]
902 %gui [GUINAME]
903
903
904 With no arguments, ``%gui`` removes all GUI support. Valid ``GUINAME``
904 With no arguments, ``%gui`` removes all GUI support. Valid ``GUINAME``
905 arguments include ``wx``, ``qt``, ``qt5``, ``gtk``, ``gtk3`` ``gtk4``, and
905 arguments include ``wx``, ``qt``, ``qt5``, ``qt6``, ``gtk``, ``gtk3`` ``gtk4``, and
906 ``tk``.
906 ``tk``.
907
907
908 Thus, to use wxPython interactively and create a running :class:`wx.App`
908 Thus, to use wxPython interactively and create a running :class:`wx.App`
@@ -936,16 +936,9 b' PyQt and PySide'
936 .. attempt at explanation of the complete mess that is Qt support
936 .. attempt at explanation of the complete mess that is Qt support
937
937
938 When you use ``--gui=qt`` or ``--matplotlib=qt``, IPython can work with either
938 When you use ``--gui=qt`` or ``--matplotlib=qt``, IPython can work with either
939 PyQt4 or PySide. There are three options for configuration here, because
939 PyQt or PySide. ``qt`` implies "use the latest version available", and it favors
940 PyQt4 has two APIs for QString and QVariant: v1, which is the default on
940 PyQt over PySide. To request a specific version, use ``qt5`` or ``qt6``. Note that
941 Python 2, and the more natural v2, which is the only API supported by PySide.
941 Qt4 is not supported with the ``--gui`` switch (and has not been for some time now).
942 v2 is also the default for PyQt4 on Python 3. IPython's code for the QtConsole
943 uses v2, but you can still use any interface in your code, since the
944 Qt frontend is in a different process.
945
946 The default will be to import PyQt4 without configuration of the APIs, thus
947 matching what most applications would expect. It will fall back to PySide if
948 PyQt4 is unavailable.
949
942
950 If specified, IPython will respect the environment variable ``QT_API`` used
943 If specified, IPython will respect the environment variable ``QT_API`` used
951 by ETS. ETS 4.0 also works with both PyQt4 and PySide, but it requires
944 by ETS. ETS 4.0 also works with both PyQt4 and PySide, but it requires
General Comments 0
You need to be logged in to leave comments. Login now