Skip to content

Commit 7dca993

Browse files
authored
Merge pull request #1171 from ales-erjavec/anyqt
[ENH] Add support for PyQt5
2 parents 9054060 + 796b0a3 commit 7dca993

File tree

218 files changed

+3029
-2155
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

218 files changed

+3029
-2155
lines changed

.travis/install_orange.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ foldable pip install -U setuptools pip codecov
22

33
# Install dependencies sequentially
44
cat requirements-core.txt \
5+
requirements-gui.txt \
56
requirements-dev.txt \
67
requirements-doc.txt |
78
while read dep; do

MANIFEST.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ recursive-include Orange/canvas/application/workflows *.ows
99

1010
recursive-include Orange/widgets *.png *.svg
1111
recursive-include Orange/widgets/_highcharts *.js *.css *.html
12+
recursive-include Orange/widgets/utils/_webview *.js
1213
recursive-include Orange/widgets/utils/plot *.fs *.vs *.gs *.obj
1314

1415
recursive-include distribute *.svg *.desktop

Orange/canvas/__main__.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,26 @@
1717

1818
import pkg_resources
1919

20-
from PyQt4.QtGui import QFont, QColor, QDesktopServices, QMessageBox
21-
from PyQt4.QtCore import Qt, QDir, QUrl
20+
from AnyQt.QtGui import QFont, QColor, QDesktopServices
21+
from AnyQt.QtWidgets import QMessageBox
22+
from AnyQt.QtCore import Qt, QDir, QUrl, QSettings
23+
24+
import AnyQt.importhooks
25+
26+
if AnyQt.USED_API == "pyqt5":
27+
# Use a backport shim to fake leftover PyQt4 imports
28+
AnyQt.importhooks.install_backport_hook('pyqt4')
2229

2330
from Orange import canvas
2431
from Orange.canvas.application.application import CanvasApplication
2532
from Orange.canvas.application.canvasmain import CanvasMainWindow
2633
from Orange.canvas.application.outputview import TextStream, ExceptHook
27-
from Orange.canvas.application.errorreporting import ErrorReporting
34+
from Orange.canvas.application.errorreporting import ErrorReporting, \
35+
handle_exception
2836

2937
from Orange.canvas.gui.splashscreen import SplashScreen
3038
from Orange.canvas.config import cache_dir
3139
from Orange.canvas import config
32-
from Orange.canvas.utils.qtcompat import QSettings
3340

3441
from Orange.canvas.registry import qt
3542
from Orange.canvas.registry import WidgetRegistry, set_global_registry
@@ -369,7 +376,7 @@ def handle_response(result):
369376
try:
370377
with patch('sys.excepthook',
371378
ExceptHook(stream=stderr, canvas=canvas_window,
372-
handledException=ErrorReporting.handle_exception)),\
379+
handledException=handle_exception)),\
373380
patch('sys.stderr', stderr),\
374381
patch('sys.stdout', stdout):
375382
status = app.exec_()

Orange/canvas/application/aboutdialog.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@
55
import sys
66
import pkg_resources
77

8-
from PyQt4.QtGui import QDialog, QDialogButtonBox, QVBoxLayout, QLabel
9-
from PyQt4.QtCore import Qt
8+
from AnyQt.QtWidgets import QDialog, QDialogButtonBox, QVBoxLayout, QLabel
9+
from AnyQt.QtCore import Qt
1010

1111
from .. import config
1212

Orange/canvas/application/addons.py

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,22 @@
2525
except ImportError:
2626
docutils = None
2727

28-
from PyQt4.QtGui import (
28+
from AnyQt.QtWidgets import (
2929
QWidget, QDialog, QLabel, QLineEdit, QTreeView, QHeaderView,
30-
QTextBrowser, QTextOption, QDialogButtonBox, QProgressDialog,
31-
QVBoxLayout, QPalette, QStandardItemModel, QStandardItem,
32-
QSortFilterProxyModel, QItemSelectionModel, QStyle, QStyledItemDelegate,
33-
QStyleOptionViewItemV4, QApplication, QHBoxLayout
30+
QTextBrowser, QDialogButtonBox, QProgressDialog,
31+
QVBoxLayout, QStyle, QStyledItemDelegate, QStyleOptionViewItem,
32+
QApplication, QHBoxLayout
3433
)
3534

36-
from PyQt4.QtCore import (
35+
from AnyQt.QtGui import (
36+
QStandardItemModel, QStandardItem, QPalette, QTextOption
37+
)
38+
39+
from AnyQt.QtCore import (
40+
QSortFilterProxyModel, QItemSelectionModel,
3741
Qt, QObject, QMetaObject, QEvent, QSize, QTimer, QThread, Q_ARG
3842
)
39-
from PyQt4.QtCore import pyqtSignal as Signal, pyqtSlot as Slot
43+
from AnyQt.QtCore import pyqtSignal as Signal, pyqtSlot as Slot
4044

4145
from ..config import ADDON_KEYWORD
4246
from ..gui.utils import message_warning, message_information, \
@@ -125,7 +129,7 @@ def editorEvent(self, event, model, option, index):
125129
if event.type() in {QEvent.MouseButtonPress, QEvent.MouseButtonRelease,
126130
QEvent.MouseButtonDblClick}:
127131
pos = event.pos()
128-
opt = QStyleOptionViewItemV4(option)
132+
opt = QStyleOptionViewItem(option)
129133
self.initStyleOption(opt, index)
130134
rect = style.subElementRect(
131135
QStyle.SE_ItemViewItemCheckIndicator, opt, widget)
@@ -222,8 +226,8 @@ def __init__(self, parent=None, **kwargs):
222226
self.__update_details
223227
)
224228
header = self.__view.header()
225-
header.setResizeMode(0, QHeaderView.Fixed)
226-
header.setResizeMode(2, QHeaderView.ResizeToContents)
229+
header.setSectionResizeMode(0, QHeaderView.Fixed)
230+
header.setSectionResizeMode(2, QHeaderView.ResizeToContents)
227231

228232
self.__details = QTextBrowser(
229233
frameShape=QTextBrowser.NoFrame,

Orange/canvas/application/application.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
44
"""
55

6-
from PyQt4.QtGui import QApplication
6+
from AnyQt.QtWidgets import QApplication
77

8-
from PyQt4.QtCore import Qt, QUrl, QEvent, pyqtSignal as Signal
8+
from AnyQt.QtCore import Qt, QUrl, QEvent, pyqtSignal as Signal
99

1010

1111
class CanvasApplication(QApplication):

Orange/canvas/application/canvasmain.py

Lines changed: 47 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,25 +11,37 @@
1111

1212
import pkg_resources
1313

14-
from PyQt4.QtGui import (
14+
from AnyQt.QtWidgets import (
1515
QMainWindow, QWidget, QAction, QActionGroup, QMenu, QMenuBar, QDialog,
16-
QFileDialog, QMessageBox, QVBoxLayout, QSizePolicy, QColor, QKeySequence,
17-
QIcon, QToolBar, QToolButton, QDockWidget, QDesktopServices, QApplication,
18-
QShortcut
16+
QFileDialog, QMessageBox, QVBoxLayout, QSizePolicy, QToolBar, QToolButton,
17+
QDockWidget, QApplication, QShortcut
1918
)
19+
from AnyQt.QtGui import QColor, QIcon, QDesktopServices, QKeySequence
2020

21-
from PyQt4.QtCore import (
22-
Qt, QEvent, QSize, QUrl, QTimer, QFile, QByteArray
21+
from AnyQt.QtCore import (
22+
Qt, QEvent, QSize, QUrl, QTimer, QFile, QByteArray, QSettings, QT_VERSION
2323
)
2424

25-
from PyQt4.QtNetwork import QNetworkDiskCache
26-
27-
from PyQt4.QtWebKit import QWebView
28-
29-
from PyQt4.QtCore import pyqtProperty as Property
30-
31-
# Compatibility with PyQt < v4.8.3
32-
from ..utils.qtcompat import QSettings
25+
if QT_VERSION < 0x50500:
26+
from AnyQt.QtWebKitWidgets import QWebView
27+
from AnyQt.QtNetwork import QNetworkDiskCache
28+
USE_WEB_ENGINE = False
29+
else:
30+
from PyQt5.QtWebEngineWidgets import QWebEngineView
31+
USE_WEB_ENGINE = True
32+
33+
from AnyQt.QtCore import pyqtProperty as Property
34+
35+
if QT_VERSION >= 0x50000:
36+
from AnyQt.QtCore import QStandardPaths
37+
def user_documents_path():
38+
"""Return the users 'Documents' folder path."""
39+
return QStandardPaths.writableLocation(
40+
QStandardPaths.DocumentsLocation)
41+
else:
42+
def user_documents_path():
43+
return QDesktopServices.storageLocation(
44+
QDesktopServices.DocumentsLocation)
3345

3446
from ..gui.dropshadow import DropShadowFrame
3547
from ..gui.dock import CollapsibleDockWidget
@@ -155,9 +167,7 @@ def __init__(self, *args):
155167

156168
self.widget_registry = None
157169

158-
self.last_scheme_dir = QDesktopServices.StandardLocation(
159-
QDesktopServices.DocumentsLocation
160-
)
170+
self.last_scheme_dir = user_documents_path()
161171
try:
162172
self.recent_schemes = config.recent_schemes()
163173
except Exception:
@@ -334,13 +344,17 @@ def setup_ui(self):
334344
objectName="help-dock",
335345
allowedAreas=Qt.RightDockWidgetArea |
336346
Qt.BottomDockWidgetArea)
337-
self.help_view = QWebView()
338-
manager = self.help_view.page().networkAccessManager()
339-
cache = QNetworkDiskCache()
340-
cache.setCacheDirectory(
341-
os.path.join(config.cache_dir(), "help", "help-view-cache")
342-
)
343-
manager.setCache(cache)
347+
self.help_dock.setAllowedAreas(Qt.NoDockWidgetArea)
348+
if USE_WEB_ENGINE:
349+
self.help_view = QWebEngineView()
350+
else:
351+
self.help_view = QWebView()
352+
manager = self.help_view.page().networkAccessManager()
353+
cache = QNetworkDiskCache()
354+
cache.setCacheDirectory(
355+
os.path.join(config.cache_dir(), "help", "help-view-cache")
356+
)
357+
manager.setCache(cache)
344358
self.help_dock.setWidget(self.help_view)
345359
self.addDockWidget(
346360
QSettings().value('help-dock/area', Qt.RightDockWidgetArea, type=int),
@@ -567,7 +581,10 @@ def setup_actions(self):
567581
triggered=self.reset_widget_settings)
568582

569583
def setup_menu(self):
570-
menu_bar = QMenuBar()
584+
if sys.platform == "darwin" and QT_VERSION >= 0x50000:
585+
self.__menu_glob = QMenuBar(None)
586+
587+
menu_bar = QMenuBar(self)
571588

572589
# File menu
573590
file_menu = QMenu(self.tr("&File"), menu_bar)
@@ -691,9 +708,7 @@ def restore(self):
691708
self.show_log_action.setChecked(
692709
settings.value("output-dock/is-visible", False, type=bool))
693710

694-
default_dir = QDesktopServices.storageLocation(
695-
QDesktopServices.DocumentsLocation
696-
)
711+
default_dir = user_documents_path()
697712

698713
self.last_scheme_dir = settings.value("last-scheme-dir", default_dir,
699714
type=str)
@@ -872,15 +887,14 @@ def open_scheme(self):
872887

873888
if self.last_scheme_dir is None:
874889
# Get user 'Documents' folder
875-
start_dir = QDesktopServices.storageLocation(
876-
QDesktopServices.DocumentsLocation)
890+
start_dir = user_documents_path()
877891
else:
878892
start_dir = self.last_scheme_dir
879893

880894
# TODO: Use a dialog instance and use 'addSidebarUrls' to
881895
# set one or more extra sidebar locations where Schemes are stored.
882896
# Also use setHistory
883-
filename = QFileDialog.getOpenFileName(
897+
filename, _ = QFileDialog.getOpenFileName(
884898
self, self.tr("Open Orange Workflow File"),
885899
start_dir, self.tr("Orange Workflow (*.ows)"),
886900
)
@@ -1179,13 +1193,11 @@ def save_scheme_as(self):
11791193
if self.last_scheme_dir is not None:
11801194
start_dir = self.last_scheme_dir
11811195
else:
1182-
start_dir = QDesktopServices.storageLocation(
1183-
QDesktopServices.DocumentsLocation
1184-
)
1196+
start_dir = user_documents_path()
11851197

11861198
start_dir = os.path.join(str(start_dir), title + ".ows")
11871199

1188-
filename = QFileDialog.getSaveFileName(
1200+
filename, _ = QFileDialog.getSaveFileName(
11891201
self, self.tr("Save Orange Workflow File"),
11901202
start_dir, self.tr("Orange Workflow (*.ows)")
11911203
)

0 commit comments

Comments
 (0)