Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PR: Add PySide2 support #84

Merged
merged 21 commits into from
May 8, 2017
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
579e104
Initial setup for PySide2 support, pretesting
dgovil Oct 26, 2016
9a9b66a
Updated __init__ dict and added PySide2 del to QtSvg.py
dgovil Oct 26, 2016
bfefe75
Added __init__ to tests to make them easy to load individually
dgovil Oct 26, 2016
50d2a81
Added comment to QtWebEngineWidgets for PySide2
dgovil Oct 26, 2016
135b49b
Updated tests to have PySide2 tests
dgovil Oct 26, 2016
6ad0112
Addressing notes by @Nodd
dgovil Nov 4, 2016
10327bd
Addressing notes by @Nodd
dgovil Nov 4, 2016
25d3c40
Merge branch 'master' into PySide2Support
ccordoba12 Jan 2, 2017
9c1a62e
Add missing newline in gitignore
ccordoba12 May 5, 2017
5b34639
Activate support for Pyside again
ccordoba12 May 5, 2017
450f65e
Update wih master
ccordoba12 May 5, 2017
123e2d3
Testing: Fix error in Appveyor and don't run ciocheck in CircleCI
ccordoba12 May 5, 2017
1865ddd
Testing: Add missing pytest dependencies on CircleCI
ccordoba12 May 5, 2017
b7f34eb
Testing: Simplify testing on CircleCI
ccordoba12 May 5, 2017
cd289f1
Testing: Skip a test that it's segfaulting in Python 3
ccordoba12 May 5, 2017
d8d8ac1
Testing: Add a package needed for PyQt 5.8
ccordoba12 May 5, 2017
4070af4
Testing: Fix missing pyqt 4 conda package in Python 3.6
ccordoba12 May 5, 2017
458bef8
Testing: Skip another test on Python 3 because it's failing
ccordoba12 May 6, 2017
7881f5c
Testing: Add a script to test PySide2
ccordoba12 May 8, 2017
2066fb9
Fix setting QT_API for PySide2
ccordoba12 May 8, 2017
d5dad47
Testing: Make tests work with PySide2
ccordoba12 May 8, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ lib64
# Other files
toread.md
.chache
.idea/
4 changes: 3 additions & 1 deletion qtpy/QtCore.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Provides QtCore classes and functions.
"""

from . import PYQT5, PYQT4, PYSIDE, PythonQtError
from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError


if PYQT5:
Expand All @@ -22,6 +22,8 @@

# Those are imported from `import *`
del pyqtSignal, pyqtSlot, pyqtProperty, QT_VERSION_STR
elif PYSIDE2:
from PySide2.QtCore import *
elif PYQT4:
from PyQt4.QtCore import *
# Those are things we inherited from Spyder that fix crazy crashes under
Expand Down
4 changes: 3 additions & 1 deletion qtpy/QtGui.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,13 @@
the ``PyQt5.QtGui`` module.
"""

from . import PYQT5, PYQT4, PYSIDE, PythonQtError
from . import PYQT5, PYQT4, PYSIDE, PYSIDE2, PythonQtError


if PYQT5:
from PyQt5.QtGui import *
elif PYSIDE2:
from PySide2.QtGui import *
elif PYQT4:
from PyQt4.Qt import QKeySequence, QTextCursor
from PyQt4.QtGui import (QAbstractTextDocumentLayout, QActionEvent, QBitmap,
Expand Down
3 changes: 3 additions & 0 deletions qtpy/QtMultimedia.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
from . import PYQT5
from . import PYQT4
from . import PYSIDE
from . import PYSIDE2


if PYQT5:
from PyQt5.QtMultimedia import *
elif PYSIDE2:
from PySide2.QtMultimedia import *
elif PYQT4:
from PyQt4.QtMultimedia import *
from PyQt4.QtGui import QSound
Expand Down
4 changes: 3 additions & 1 deletion qtpy/QtNetwork.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
Provides QtNetwork classes and functions.
"""

from . import PYQT5, PYQT4, PYSIDE, PythonQtError
from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError


if PYQT5:
from PyQt5.QtNetwork import *
elif PYSIDE2:
from PySide2.QtNetwork import *
elif PYQT4:
from PyQt4.QtNetwork import *
elif PYSIDE:
Expand Down
4 changes: 3 additions & 1 deletion qtpy/QtPrintSupport.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@
Provides QtPrintSupport classes and functions.
"""

from . import PYQT5, PYQT4, PYSIDE, PythonQtError
from . import PYQT5, PYQT4,PYSIDE2, PYSIDE, PythonQtError


if PYQT5:
from PyQt5.QtPrintSupport import *
elif PYSIDE2:
from PySide2.QtPrintSupport import *
elif PYQT4:
from PyQt4.QtGui import (QAbstractPrintDialog, QPageSetupDialog,
QPrintDialog, QPrintEngine, QPrintPreviewDialog,
Expand Down
7 changes: 5 additions & 2 deletions qtpy/QtSvg.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,14 @@
"""Provides QtSvg classes and functions."""

# Local imports
from . import PYQT4, PYQT5, PYSIDE, PythonQtError
from . import PYQT4, PYSIDE2, PYQT5, PYSIDE, PythonQtError

if PYQT5:
from PyQt5.QtSvg import (QGraphicsSvgItem, QSvgGenerator, QSvgRenderer,
QSvgWidget)
elif PYSIDE2:
from PySide2.QtSvg import (QGraphicsSvgItem, QSvgGenerator, QSvgRenderer,
QSvgWidget)
elif PYQT4:
from PyQt4.QtSvg import (QGraphicsSvgItem, QSvgGenerator, QSvgRenderer,
QSvgWidget)
Expand All @@ -22,4 +25,4 @@
else:
raise PythonQtError('No Qt bindings could be found')

del PYQT4, PYQT5, PYSIDE
del PYQT4, PYQT5, PYSIDE, PYSIDE2
4 changes: 3 additions & 1 deletion qtpy/QtTest.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
Provides QtTest and functions
"""

from . import PYQT5, PYQT4, PYSIDE, PythonQtError
from . import PYQT5,PYSIDE2, PYQT4, PYSIDE, PythonQtError


if PYQT5:
from PyQt5.QtTest import QTest
elif PYSIDE2:
from PySide2.QtTest import QTest
elif PYQT4:
from PyQt4.QtTest import QTest as OldQTest

Expand Down
14 changes: 13 additions & 1 deletion qtpy/QtWebEngineWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
Provides QtWebEngineWidgets classes and functions.
"""

from . import PYQT5, PYQT4, PYSIDE, PythonQtError
from . import PYQT5,PYSIDE2, PYQT4, PYSIDE, PythonQtError


# To test if we are using WebEngine or WebKit
Expand All @@ -27,6 +27,18 @@
from PyQt5.QtWebKitWidgets import QWebView as QWebEngineView
from PyQt5.QtWebKit import QWebSettings as QWebEngineSettings
WEBENGINE = False
elif PYSIDE2:
try:
from PySide2.QtWebEngineWidgets import QWebEnginePage
from PySide2.QtWebEngineWidgets import QWebEngineView
from PySide2.QtWebEngineWidgets import QWebEngineSettings
except ImportError:
from PySide2.QtWebKitWidgets import QWebPage as QWebEnginePage
from PySide2.QtWebKitWidgets import QWebView as QWebEngineView
#: Current PySide2 builds seem to be missing this.
#: I'll leave it in for now because the final builds should have it
from PySide2.QtWebKit import QWebSettings as QWebEngineSettings
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It means that right now importing QtWebEngineWidgets will fail with pyside2 even if QWebEngineSettings is not used ? I'm in favor of commenting this line for now and readding it when pyside2 includes QWebSettings.

WEBENGINE = False
elif PYQT4:
from PyQt4.QtWebKit import QWebPage as QWebEnginePage
from PyQt4.QtWebKit import QWebView as QWebEngineView
Expand Down
4 changes: 3 additions & 1 deletion qtpy/QtWidgets.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,15 @@
were the ``PyQt5.QtWidgets`` module.
"""

from . import PYQT5, PYQT4, PYSIDE, PythonQtError
from . import PYQT5, PYSIDE2, PYQT4, PYSIDE, PythonQtError
from ._patch.qcombobox import patch_qcombobox
from ._patch.qheaderview import introduce_renamed_methods_qheaderview


if PYQT5:
from PyQt5.QtWidgets import *
elif PYSIDE2:
from PySide2.QtWidgets import *
elif PYQT4:
from PyQt4.QtGui import *
QStyleOptionViewItem = QStyleOptionViewItemV4
Expand Down
32 changes: 28 additions & 4 deletions qtpy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@
>>> print(QtWidgets.QWidget)


PySide2
======

Set the QT_API environment variable to 'pyside2' before importing other
packages::

>>> import os
>>> os.environ['QT_API'] = 'pyside2'
>>> from qtpy import QtGui, QtWidgets, QtCore
>>> print(QtWidgets.QWidget)

PyQt4
=====

Expand Down Expand Up @@ -66,14 +77,16 @@
]
#: names of the expected PySide api
PYSIDE_API = ['pyside']
#: names of the expected PySide2 api
PYSIDE2_API = ['pyside2']

os.environ.setdefault(QT_API, 'pyqt5')
API = os.environ[QT_API].lower()
assert API in (PYQT5_API + PYQT4_API + PYSIDE_API)
assert API in (PYQT5_API + PYQT4_API + PYSIDE_API+PYSIDE2_API)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Spaces around the + operator please !


is_old_pyqt = is_pyqt46 = False
PYQT5 = True
PYQT4 = PYSIDE = False
PYQT4 = PYSIDE = PYSIDE2 = False


class PythonQtError(Exception):
Expand All @@ -89,6 +102,17 @@ class PythonQtError(Exception):
except ImportError:
API = os.environ['QT_API'] = 'pyqt'

if API in PYSIDE2_API:
try:
from PySide2 import __version__ as PYSIDE_VERSION # analysis:ignore
from PySide2.QtCore import __version__ as QT_VERSION # analysis:ignore

PYQT_VERSION = None
PYQT5 = False
PYSIDE2 = True
except ImportError:
API = os.environ['QT_API'] = 'pyqt4'

if API in PYQT4_API:
try:
import sip
Expand Down Expand Up @@ -119,13 +143,13 @@ class PythonQtError(Exception):
from PySide import __version__ as PYSIDE_VERSION # analysis:ignore
from PySide.QtCore import __version__ as QT_VERSION # analysis:ignore
PYQT_VERSION = None
PYQT5 = False
PYQT5 = PYSIDE2 = False
PYSIDE = True
except ImportError:
raise PythonQtError('No Qt bindings could be found')

API_NAME = {'pyqt5': 'PyQt5', 'pyqt': 'PyQt4', 'pyqt4': 'PyQt4',
'pyside': 'PySide'}[API]
'pyside': 'PySide', 'pyside2':'PySide2'}[API]
if PYQT4:
import sip
try:
Expand Down
Empty file added qtpy/tests/__init__.py
Empty file.
12 changes: 12 additions & 0 deletions qtpy/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,18 @@ def pytest_report_header(config):
except AttributeError:
versions += 'unknown version'

versions += os.linesep
versions += 'PySide2: '

try:
import PySide2
from PySide2 import QtCore
versions += "PySide: {0} - Qt: {1}".format(PySide2.__version__, QtCore.__version__)
except ImportError:
versions += 'not installed'
except AttributeError:
versions += 'unknown version'

versions += os.linesep

return versions
12 changes: 12 additions & 0 deletions qtpy/tests/test_main.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ def assert_pyside():
assert QtWidgets.QWidget is PySide.QtGui.QWidget
assert QtWebEngineWidgets.QWebEnginePage is PySide.QtWebKit.QWebPage

def assert_pyside2():
"""
Make sure that we are using PySide
"""
import PySide2
assert QtCore.QEvent is PySide2.QtCore.QEvent
assert QtGui.QPainter is PySide2.QtGui.QPainter
assert QtWidgets.QWidget is PySide2.QtGui.QWidget
# The current builds of PySide2 don't seem to have this yet
# assert QtWebEngineWidgets.QWebEnginePage is PySide2.QtWebKit.QWebPage

def assert_pyqt4():
"""
Expand Down Expand Up @@ -52,6 +62,8 @@ def test_qt_api():
assert_pyqt4()
elif QT_API == 'pyqt5':
assert_pyqt5()
elif QT_API == 'pyside2':
assert_pyside2()
else:
# If the tests are run locally, USE_QT_API and QT_API may not be
# defined, but we still want to make sure qtpy is behaving sensibly.
Expand Down
12 changes: 8 additions & 4 deletions qtpy/uic.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import os

from . import PYSIDE, PYQT4, PYQT5
from . import PYSIDE, PYSIDE2, PYQT4, PYQT5
from .QtWidgets import QComboBox

__all__ = ['loadUi']
Expand All @@ -13,7 +13,7 @@

from PyQt4.uic import loadUi

elif PYSIDE:
else:

# In PySide, loadUi does not exist, so we define it using QUiLoader, and
# then make sure we expose that function. This is adapted from qt-helpers
Expand Down Expand Up @@ -77,8 +77,12 @@
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
# DEALINGS IN THE SOFTWARE.

from PySide.QtCore import QMetaObject
from PySide.QtUiTools import QUiLoader
if PYSIDE:
from PySide.QtCore import QMetaObject
from PySide.QtUiTools import QUiLoader
elif PYSIDE2:
from PySide2.QtCore import QMetaObject
from PySide2.QtUiTools import QUiLoader

class UiLoader(QUiLoader):
"""
Expand Down