Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 63ad9f2

Browse files
committed
Merge pull request #81 from stonebig/master
PyQt5 compatibility
2 parents dd446ce + f80455e commit 63ad9f2

File tree

8 files changed

+141
-63
lines changed

8 files changed

+141
-63
lines changed

make.py

Lines changed: 48 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ def py_arch(self):
240240
@property
241241
def prepath(self):
242242
"""Return PATH contents to be prepend to the environment variable"""
243-
path = [r"Lib\site-packages\PyQt4",
243+
path = [r"Lib\site-packages\PyQt5", r"Lib\site-packages\PyQt4",
244244
"", # Python root directory (python.exe)
245245
"DLLs", "Scripts", r"..\tools", r"..\tools\mingw32\bin"
246246
]
@@ -466,6 +466,11 @@ def _install_required_packages(self):
466466
self.install_package('%s-([0-9\.]*[a-z]*[0-9]?)(.*)(\.exe|\.whl)' %
467467
'setuptools', install_options=['--upgrade', '--no-deps'])
468468

469+
#Pyqt5 (doesn't currently install in build this way, reason unclear)
470+
#self.install_package(
471+
# 'PyQt5-([0-9\.\-]*)-gpl-Py%s-Qt([0-9\.\-]*)%s.exe'
472+
# % (self.python_version, self.pyqt_arch))
473+
469474
# Install 'main packages' first (was before Wheel idea, keep for now)
470475
for happy_few in['pip', 'wheel', 'pywin32', 'six', 'numpy', 'spyder',
471476
'scipy', 'matplotlib', 'pandas']:
@@ -549,17 +554,29 @@ def _create_launchers(self):
549554
# args='register_python',
550555
# workdir='${WINPYDIR}\Scripts')
551556

552-
self.create_launcher('Qt Demo.exe', 'qt.ico', args='qtdemo.pyw',
553-
workdir=r'${WINPYDIR}\Lib\site-packages\PyQt4\examples\demos\qtdemo')
554-
self.create_launcher('Qt Assistant.exe', 'qtassistant.ico',
555-
command=r'${WINPYDIR}\Lib\site-packages\PyQt4\assistant.exe',
556-
workdir=r'${WINPYDIR}')
557-
self.create_launcher('Qt Designer.exe', 'qtdesigner.ico',
558-
command=r'${WINPYDIR}\Lib\site-packages\PyQt4\designer.exe',
559-
workdir=r'${WINPYDIR}')
560-
self.create_launcher('Qt Linguist.exe', 'qtlinguist.ico',
561-
command=r'${WINPYDIR}\Lib\site-packages\PyQt4\linguist.exe',
562-
workdir=r'${WINPYDIR}')
557+
python_lib_dir = osp.join(self.winpydir, self.python_name,
558+
r"Lib\site-packages")
559+
# manage Qt4, Qt5
560+
for QtV in (5, 4):
561+
PyQt = 'PyQt%s' % QtV
562+
QtDemo_path = 'demos\qtdemo' if QtV == 4 else 'qtdemo'
563+
if osp.isdir(osp.join(python_lib_dir, PyQt)):
564+
self.create_launcher('Qt%s Demo.exe' % QtV, 'qt.ico',
565+
args='qtdemo.pyw', workdir=
566+
r'${WINPYDIR}\Lib\site-packages\%s\examples\%s' %
567+
(PyQt, QtDemo_path) )
568+
self.create_launcher('Qt%s Assistant.exe' % QtV,
569+
'qtassistant.ico',
570+
command=r'${WINPYDIR}\Lib\site-packages\%s\assistant.exe' %
571+
PyQt, workdir=r'${WINPYDIR}')
572+
self.create_launcher('Qt%s Designer.exe' % QtV,
573+
'qtdesigner.ico',
574+
command=r'${WINPYDIR}\Lib\site-packages\%s\designer.exe' %
575+
PyQt, workdir=r'${WINPYDIR}')
576+
self.create_launcher('Qt%s Linguist.exe' % QtV,
577+
'qtlinguist.ico',
578+
command=r'${WINPYDIR}\Lib\site-packages\%s\linguist.exe' %
579+
PyQt, workdir=r'${WINPYDIR}')
563580
if self.python_version[0] == '3':
564581
ipython_exe = 'ipython3.exe'
565582
ipython_scr = 'ipython3-script.py'
@@ -919,8 +936,10 @@ def _create_batch_scripts(self):
919936
call %~dp0env.bat
920937
call %~dp0register_python.bat --all""")
921938
self.create_python_batch('wpcp.bat', 'wpcp', workdir='Scripts')
922-
self.create_python_batch('pyqt_demo.bat', 'qtdemo.pyw',
923-
workdir=r'Lib\site-packages\PyQt4\examples\demos\qtdemo')
939+
self.create_python_batch('pyqt4_demo.bat', 'qtdemo.pyw',
940+
workdir=r'Lib\site-packages\PyQt4\examples\demos\qtdemo')
941+
self.create_python_batch('pyqt5_demo.bat', 'qtdemo.pyw',
942+
workdir=r'Lib\site-packages\PyQt5\examples\qtdemo')
924943

925944
# pre-run wingw batch
926945
print('now pre-running extra mingw')
@@ -1155,31 +1174,29 @@ def make_all(build_number, release_level, pyver,
11551174
# DO create only what version at a time
11561175
# You may have to manually delete previous build\winpython-.. directory
11571176

1158-
make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1159-
verbose=False, archis=(32, ))
1160-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1161-
# verbose=False, archis=(64, ), flavor='')
1162-
#make_all(7, '', pyver='3.3', rootdir=r'D:\Winpython',
1177+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
1178+
# verbose=False, archis=(32, ))
1179+
make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
1180+
verbose=False, archis=(64, ), flavor='')
1181+
#make_all(8, '', pyver='3.3', rootdir=r'D:\Winpython',
11631182
# verbose=False, archis=(32, ))
1164-
#make_all(7, '', pyver='3.3', rootdir=r'D:\Winpython',
1183+
#make_all(8, '', pyver='3.3', rootdir=r'D:\Winpython',
11651184
# verbose=False, archis=(64, ))
1166-
#make_all(4, '', pyver='2.7', rootdir=r'D:\Winpython',
1185+
#make_all(5, '', pyver='2.7', rootdir=r'D:\Winpython',
11671186
# verbose=False, archis=(32, ))
1168-
#make_all(4, '', pyver='2.7', rootdir=r'D:\Winpython',
1187+
#make_all(5, '', pyver='2.7', rootdir=r'D:\Winpython',
11691188
# verbose=False, archis=(64, ))
1170-
#make_all(4, '', pyver='2.7', rootdir=r'D:\Winpython',
1171-
# verbose=False, archis=(64, ), flavor='FlavorRfull')
1172-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1189+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
11731190
# verbose=False, archis=(64, ), flavor='FlavorIgraph')
1174-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1191+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
11751192
# verbose=False, archis=(32, ), flavor='FlavorKivy')
1176-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1193+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
11771194
# verbose=False, archis=(32, ), flavor='FlavorRfull')
1178-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1195+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
11791196
# verbose=False, archis=(64, ), flavor='FlavorRfull')
1180-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1197+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
11811198
# verbose=False, archis=(32, ), flavor='FlavorJulia')
1182-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1199+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
11831200
# verbose=False, archis=(64, ), flavor='FlavorJulia')
1184-
#make_all(2, '', pyver='3.4', rootdir=r'D:\Winpython',
1201+
#make_all(3, '', pyver='3.4', rootdir=r'D:\Winpython',
11851202
# verbose=False, archis=(32, ), flavor='FlavorRJulia')

winpython/controlpanel.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,9 @@ def __init__(self, parent, process, winname):
167167
self.setShowGrid(False)
168168

169169
def reset_model(self):
170-
self.model.reset()
170+
# self.model.reset() is deprecated in Qt5
171+
self.model.beginResetModel()
172+
self.model.endResetModel()
171173
self.horizontalHeader().setStretchLastSection(True)
172174
for colnb in (ACTION, CHECK, NAME, VERSION):
173175
self.resizeColumnToContents(colnb)

winpython/qt/QtCore.py

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,26 @@
33
# Copyright © 2011 Pierre Raybaut
44
# Licensed under the terms of the MIT License
55
# (copied from Spyder source code [spyderlib.qt])
6+
#
7+
# Qt5 migration would not have been possible without
8+
# 2014-2015 Spyder Development Team work
9+
# (MIT License too, same parent project)
610

711
import os
812

9-
if os.environ['QT_API'] == 'pyqt':
13+
if os.environ['QT_API'] == 'pyqt5':
14+
from PyQt5.QtCore import * # analysis:ignore
15+
from PyQt5.QtCore import QCoreApplication
16+
from PyQt5.QtCore import pyqtSignal as Signal
17+
from PyQt5.QtCore import pyqtSlot as Slot
18+
from PyQt5.QtCore import pyqtProperty as Property
19+
from PyQt5.QtCore import QT_VERSION_STR as __version__
20+
elif os.environ['QT_API'] == 'pyqt':
1021
from PyQt4.QtCore import * # analysis:ignore
11-
from PyQt4.Qt import QCoreApplication # analysis:ignore
12-
from PyQt4.Qt import Qt # analysis:ignore
22+
# from PyQt4.Qt import QCoreApplication # analysis:ignore
23+
# from PyQt4.Qt import Qt # analysis:ignore
24+
from PyQt4.QtCore import QCoreApplication # analysis:ignore
25+
from PyQt4.QtCore import Qt # analysis:ignore
1326
from PyQt4.QtCore import pyqtSignal as Signal # analysis:ignore
1427
from PyQt4.QtCore import pyqtSlot as Slot # analysis:ignore
1528
from PyQt4.QtCore import pyqtProperty as Property # analysis:ignore

winpython/qt/QtGui.py

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,21 @@
33
# Copyright © 2011 Pierre Raybaut
44
# Licensed under the terms of the MIT License
55
# (copied from Spyder source code [spyderlib.qt])
6+
#
7+
# Qt5 migration would not have been possible without
8+
# 2014-2015 Spyder Development Team work
9+
# (MIT License too, same parent project)
610

711
import os
812

9-
if os.environ['QT_API'] == 'pyqt':
13+
if os.environ['QT_API'] == 'pyqt5':
14+
from PyQt5.QtCore import QSortFilterProxyModel # analysis:ignore
15+
from PyQt5.QtPrintSupport import (QPrinter, QPrintDialog, # analysis:ignore
16+
QAbstractPrintDialog)
17+
from PyQt5.QtPrintSupport import QPrintPreviewDialog # analysis:ignore
18+
from PyQt5.QtGui import * # analysis:ignore
19+
from PyQt5.QtWidgets import * # analysis:ignore
20+
elif os.environ['QT_API'] == 'pyqt':
1021
from PyQt4.Qt import QKeySequence, QTextCursor # analysis:ignore
1122
from PyQt4.QtGui import * # analysis:ignore
1223
else:

winpython/qt/QtSvg.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@
66

77
import os
88

9-
if os.environ['QT_API'] == 'pyqt':
9+
if os.environ['QT_API'] == 'pyqt5':
10+
from PyQt5.QtSvg import * # analysis:ignore
11+
elif os.environ['QT_API'] == 'pyqt':
1012
from PyQt4.QtSvg import * # analysis:ignore
1113
else:
1214
from PySide.QtSvg import * # analysis:ignore

winpython/qt/QtWebKit.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,11 @@
66

77
import os
88

9-
if os.environ['QT_API'] == 'pyqt':
10-
from PyQt4.QtWebKit import * # analysis:ignore
9+
if os.environ['QT_API'] == 'pyqt5':
10+
from PyQt5.QtWebKitWidgets import QWebPage, QWebView # analysis:ignore
11+
from PyQt5.QtWebKit import QWebSettings # analysis:ignore
12+
elif os.environ['QT_API'] == 'pyqt':
13+
from PyQt4.QtWebKit import (QWebPage, QWebView, # analysis:ignore
14+
QWebSettings)
1115
else:
1216
from PySide.QtWebKit import * # analysis:ignore

winpython/qt/__init__.py

Lines changed: 36 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# -*- coding: utf-8 -*-
22
#
3-
# Copyright © 2011 Pierre Raybaut
3+
# Copyright © 2011-2012 Pierre Raybaut
4+
# © 2012-2014 anatoly techtonik
45
# Licensed under the terms of the MIT License
56
# (copied from Spyder source code [spyderlib.qt])
67

@@ -9,30 +10,46 @@
910
import os
1011

1112
os.environ.setdefault('QT_API', 'pyqt')
12-
assert os.environ['QT_API'] in ('pyqt', 'pyside')
13+
assert os.environ['QT_API'] in ('pyqt5', 'pyqt', 'pyside')
1314

1415
API = os.environ['QT_API']
15-
API_NAME = {'pyqt': 'PyQt4', 'pyside': 'PySide'}[API]
16-
17-
if API == 'pyqt':
18-
# We do not force QString, QVariant, ... API to #1 or #2 anymore
19-
# as spyderlib is now compatible with both APIs
20-
# import sip
21-
# try:
22-
# sip.setapi('QString', 2)
23-
# sip.setapi('QVariant', 2)
24-
# except AttributeError:
25-
# # PyQt < v4.6: in future version, we should warn the user
26-
# # that PyQt is outdated and won't be supported by Spyder >v2.1
27-
# pass
16+
API_NAME = {'pyqt5': 'PyQt5', 'pyqt': 'PyQt4', 'pyside': 'PySide'}[API]
17+
18+
PYQT5 = False
19+
20+
if API == 'pyqt5':
2821
try:
29-
from PyQt4.QtCore import PYQT_VERSION_STR as __version__
22+
from PyQt5.QtCore import PYQT_VERSION_STR as __version__
23+
is_old_pyqt = False
24+
is_pyqt46 = False
25+
PYQT5 = True
26+
except ImportError:
27+
pass
28+
elif API == 'pyqt':
29+
# Spyder 2.3 is compatible with both #1 and #2 PyQt API,
30+
# but to avoid issues with IPython and other Qt plugins
31+
# we choose to support only API #2 for 2.4+
32+
import sip
33+
try:
34+
sip.setapi('QString', 2)
35+
sip.setapi('QVariant', 2)
36+
sip.setapi('QDate', 2)
37+
sip.setapi('QDateTime', 2)
38+
sip.setapi('QTextStream', 2)
39+
sip.setapi('QTime', 2)
40+
sip.setapi('QUrl', 2)
41+
except AttributeError:
42+
# PyQt < v4.6. The actual check is done by requirements.check_qt()
43+
# call from spyder.py
44+
pass
45+
46+
try:
47+
from PyQt4.QtCore import PYQT_VERSION_STR as __version__ # analysis:ignore
3048
except ImportError:
3149
# Switching to PySide
3250
API = os.environ['QT_API'] = 'pyside'
3351
API_NAME = 'PySide'
3452
else:
35-
__version_info__ = tuple(__version__.split('.')+['final', 1])
3653
is_old_pyqt = __version__.startswith(('4.4', '4.5', '4.6', '4.7'))
3754
is_pyqt46 = __version__.startswith('4.6')
3855
import sip
@@ -41,10 +58,11 @@
4158
except AttributeError:
4259
pass
4360

61+
4462
if API == 'pyside':
4563
try:
4664
from PySide import __version__ # analysis:ignore
4765
except ImportError:
4866
raise ImportError("Spyder requires PySide or PyQt to be installed")
4967
else:
50-
is_old_pyqt = is_pyqt46 = False
68+
is_old_pyqt = is_pyqt46 = False

winpython/qthelpers.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,19 @@
33
# Copyright © 2009-2011 Pierre Raybaut
44
# Licensed under the terms of the MIT License
55
# (copied from Spyder source code [spyderlib.qt])
6+
#
7+
# Qt5 migration would not have been possible without
8+
# 2014-2015 Spyder Development Team work
9+
# (MIT License too, same parent project)
610

711
"""Qt utilities"""
812

913
from winpython.qt.QtGui import (QAction, QStyle, QWidget, QIcon, QApplication,
10-
QMenu, QKeySequence, QToolButton)
11-
from winpython.qt.QtCore import (SIGNAL, Qt, QLocale, QTranslator,
12-
QLibraryInfo, QEvent)
14+
QLabel, QVBoxLayout, QHBoxLayout, QLineEdit,
15+
QKeyEvent, QMenu, QKeySequence, QToolButton,
16+
QPixmap)
17+
from winpython.qt.QtCore import (Signal, QObject, Qt, QLocale, QTranslator,
18+
QLibraryInfo, QEvent, Slot)
1319
from winpython.qt.compat import to_qvariant, from_qvariant
1420

1521
import os
@@ -29,13 +35,16 @@ def get_icon(name):
2935

3036
class MacApplication(QApplication):
3137
"""Subclass to be able to open external files with our Mac app"""
38+
open_external_file = Signal(str)
39+
3240
def __init__(self, *args):
3341
QApplication.__init__(self, *args)
3442

3543
def event(self, event):
3644
if event.type() == QEvent.FileOpen:
3745
fname = str(event.file())
38-
self.emit(SIGNAL('open_external_file(QString)'), fname)
46+
# PyQt4 old SIGNAL: self.emit(SIGNAL('open_external_file(QString)'), fname)
47+
self.open_external_file.emit(fname)
3948
return QApplication.event(self, event)
4049

4150

@@ -153,9 +162,11 @@ def create_action(parent, text, shortcut=None, icon=None, tip=None,
153162
"""Create a QAction"""
154163
action = QAction(text, parent)
155164
if triggered is not None:
156-
parent.connect(action, SIGNAL("triggered()"), triggered)
165+
# PyQt4 old SIGNAL: parent.connect(action, SIGNAL("triggered()"), triggered)
166+
action.triggered.connect(triggered)
157167
if toggled is not None:
158-
parent.connect(action, SIGNAL("toggled(bool)"), toggled)
168+
# PyQt4 old SIGNAL: parent.connect(action, SIGNAL("toggled(bool)"), toggled)
169+
action.toggled.connect(toggled)
159170
action.setCheckable(True)
160171
if icon is not None:
161172
if is_text_string(icon):

0 commit comments

Comments
 (0)