Skip to content

Commit

Permalink
Merge pull request #22196 from hmaarrfk/optional_webengine
Browse files Browse the repository at this point in the history
PR: Make QtWebEngine Optional
  • Loading branch information
ccordoba12 authored Jul 8, 2024
2 parents ca726b1 + 6cc6a98 commit 759536e
Show file tree
Hide file tree
Showing 7 changed files with 57 additions and 14 deletions.
7 changes: 7 additions & 0 deletions spyder/api/plugins/new_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,13 @@ class SpyderPluginV2(QObject, SpyderActionMixin, SpyderConfigurationObserver,
# disabled. Default: True
CAN_BE_DISABLED = True

# Qt Web Widgets may be a heavy dependency for many packagers
# (e.g. conda-forge)
# We thus ask plugins to declare whether or not they need
# web widgets to enhance the distribution of Spyder to users
# https://github.com/spyder-ide/spyder/pull/22196#issuecomment-2189377043
REQUIRE_WEB_WIDGETS = False

# --- API: Signals -------------------------------------------------------
# ------------------------------------------------------------------------
# Signals here are automatically connected by the Spyder main window and
Expand Down
23 changes: 16 additions & 7 deletions spyder/app/mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,10 @@
from qtpy import QtSvg # analysis:ignore

# Avoid a bug in Qt: https://bugreports.qt.io/browse/QTBUG-46720
from qtpy import QtWebEngineWidgets # analysis:ignore
try:
from qtpy.QtWebEngineWidgets import WEBENGINE
except ImportError:
WEBENGINE = False

from qtawesome.iconic_font import FontError

Expand Down Expand Up @@ -724,12 +727,6 @@ def setup(self):

for plugin in all_plugins.values():
plugin_name = plugin.NAME
# Disable plugins that use web widgets (currently Help and Online
# Help) if the user asks for it.
# See spyder-ide/spyder#16518
if self._cli_options.no_web_widgets:
if "help" in plugin_name:
continue

plugin_main_attribute_name = (
self._INTERNAL_PLUGINS_MAPPING[plugin_name]
Expand Down Expand Up @@ -772,6 +769,18 @@ def setup(self):
if plugin_name in enabled_plugins:
PluginClass = internal_plugins[plugin_name]
if issubclass(PluginClass, SpyderPluginV2):
# Disable plugins that use web widgets (currently Help and
# Online Help) if the user asks for it.
# See spyder-ide/spyder#16518
# The plugins that require QtWebengine must declare
# themselves as needing that dependency
# https://github.com/spyder-ide/spyder/pull/22196#issuecomment-2189377043
if PluginClass.REQUIRE_WEB_WIDGETS and (
not WEBENGINE or
self._cli_options.no_web_widgets
):
continue

PLUGIN_REGISTRY.register_plugin(self, PluginClass,
external=False)

Expand Down
1 change: 1 addition & 0 deletions spyder/plugins/help/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class Help(SpyderDockablePlugin):
CONF_FILE = False
LOG_PATH = get_conf_path(CONF_SECTION)
DISABLE_ACTIONS_WHEN_HIDDEN = False
REQUIRE_WEB_WIDGETS = True

# Signals
sig_focus_changed = Signal() # TODO: What triggers this?
Expand Down
11 changes: 9 additions & 2 deletions spyder/plugins/help/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
from qtpy import PYQT5, PYQT6
from qtpy.QtCore import Qt, QUrl, Signal, Slot, QPoint
from qtpy.QtGui import QColor
from qtpy.QtWebEngineWidgets import WEBENGINE, QWebEnginePage
from qtpy.QtWidgets import (QActionGroup, QLabel, QLineEdit,
QMessageBox, QSizePolicy, QStackedWidget,
QVBoxLayout, QWidget)
Expand All @@ -37,11 +36,16 @@
from spyder.utils.image_path_manager import get_image_path
from spyder.utils.palette import SpyderPalette
from spyder.utils.qthelpers import start_file
from spyder.widgets.browser import FrameWebView
from spyder.widgets.comboboxes import EditableComboBox
from spyder.widgets.findreplace import FindReplace
from spyder.widgets.simplecodeeditor import SimpleCodeEditor

# In case WebEngine is not available (e.g. in Conda-forge)
try:
from qtpy.QtWebEngineWidgets import WEBENGINE
except ImportError:
WEBENGINE = False


# --- Constants
# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -158,6 +162,9 @@ def __init__(self, parent):
QWidget.__init__(self, parent)
SpyderWidgetMixin.__init__(self, class_parent=parent)

from qtpy.QtWebEngineWidgets import QWebEnginePage
from spyder.widgets.browser import FrameWebView

self.webview = FrameWebView(self)
self.webview.setup()

Expand Down
12 changes: 9 additions & 3 deletions spyder/plugins/ipythonconsole/widgets/main_widget.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
from qtpy.QtCore import Signal, Slot
from qtpy.QtGui import QColor, QKeySequence
from qtpy.QtPrintSupport import QPrintDialog, QPrinter
from qtpy.QtWebEngineWidgets import WEBENGINE
from qtpy.QtWidgets import (
QApplication, QHBoxLayout, QLabel, QMessageBox, QVBoxLayout, QWidget)
from traitlets.config.loader import Config, load_pyconfig_files
Expand Down Expand Up @@ -58,11 +57,16 @@
from spyder.utils.palette import SpyderPalette
from spyder.utils.stylesheet import AppStyle
from spyder.utils.workers import WorkerManager
from spyder.widgets.browser import FrameWebView
from spyder.widgets.findreplace import FindReplace
from spyder.widgets.tabs import Tabs
from spyder.widgets.printer import SpyderPrinter

# In case WebEngine is not available (e.g. in Conda-forge)
try:
from qtpy.QtWebEngineWidgets import WEBENGINE
except ImportError:
WEBENGINE = False


# Logging
logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -252,7 +256,7 @@ def __init__(self, name=None, plugin=None, parent=None):
self.enable_infowidget = True
if plugin:
cli_options = plugin.get_command_line_options()
if cli_options.no_web_widgets:
if cli_options.no_web_widgets or not WEBENGINE:
self.enable_infowidget = False

# Attrs for testing
Expand Down Expand Up @@ -288,6 +292,8 @@ def __init__(self, name=None, plugin=None, parent=None):

# Info widget
if self.enable_infowidget:
from spyder.widgets.browser import FrameWebView

self.infowidget = FrameWebView(self)
if WEBENGINE:
self.infowidget.page().setBackgroundColor(
Expand Down
1 change: 1 addition & 0 deletions spyder/plugins/onlinehelp/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class OnlineHelp(SpyderDockablePlugin):
CONF_FILE = False
WIDGET_CLASS = PydocBrowser
LOG_PATH = get_conf_path(NAME)
REQUIRE_WEB_WIDGETS = True

# --- Signals
# ------------------------------------------------------------------------
Expand Down
16 changes: 14 additions & 2 deletions spyder/plugins/onlinehelp/widgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,17 +17,21 @@
# Third party imports
from qtpy.QtCore import Qt, QThread, QUrl, Signal, Slot
from qtpy.QtGui import QCursor
from qtpy.QtWebEngineWidgets import WEBENGINE
from qtpy.QtWidgets import QApplication, QLabel, QVBoxLayout

# Local imports
from spyder.api.translations import _
from spyder.api.widgets.main_widget import PluginMainWidget
from spyder.plugins.onlinehelp.pydoc_patch import _start_server, _url_handler
from spyder.widgets.browser import FrameWebView, WebViewActions
from spyder.widgets.comboboxes import UrlComboBox
from spyder.widgets.findreplace import FindReplace

# In case WebEngine is not available (e.g. in Conda-forge)
try:
from qtpy.QtWebEngineWidgets import WEBENGINE
except ImportError:
WEBENGINE = False


# --- Constants
# ----------------------------------------------------------------------------
Expand Down Expand Up @@ -139,6 +143,8 @@ class PydocBrowser(PluginMainWidget):
"""

def __init__(self, name=None, plugin=None, parent=None):
from spyder.widgets.browser import FrameWebView

super().__init__(name, plugin, parent=parent)

self._is_running = False
Expand Down Expand Up @@ -193,6 +199,8 @@ def get_focus_widget(self):
return self.url_combo

def setup(self):
from spyder.widgets.browser import WebViewActions

# Actions
home_action = self.create_action(
PydocBrowserActions.Home,
Expand Down Expand Up @@ -243,6 +251,8 @@ def setup(self):
self.sig_toggle_view_changed.connect(self.initialize)

def update_actions(self):
from spyder.widgets.browser import WebViewActions

stop_action = self.get_action(WebViewActions.Stop)
refresh_action = self.get_action(WebViewActions.Refresh)

Expand Down Expand Up @@ -271,6 +281,8 @@ def _continue_initialization(self):

def _handle_url_combo_activation(self):
"""Load URL from combo box first item."""
from spyder.widgets.browser import WebViewActions

if not self._is_running:
text = str(self.url_combo.currentText())
self.go_to(self.text_to_url(text))
Expand Down

0 comments on commit 759536e

Please sign in to comment.