Skip to content

Commit d0a8e2d

Browse files
committed
Adding PyQt5 support
- Updated travis - Now PYTEST_QT_FORCE_PYQT may assume values "4" or "5" to choose which PyQt API to use - qt_compat now has to be aware of the differences between PyQt4 and PyQt5
1 parent 2ab6d4b commit d0a8e2d

File tree

6 files changed

+56
-34
lines changed

6 files changed

+56
-34
lines changed

.travis.yml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ virtualenv:
88
system_site_packages: true
99

1010
env:
11-
- PYTEST_VERSION=2.6.4 PYTEST_QT_FORCE_PYQT=true
12-
- PYTEST_VERSION=2.6.4 PYTEST_QT_FORCE_PYQT=false
13-
- PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=true
14-
- PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=false
11+
# - PYTEST_VERSION=2.6.4 PYTEST_QT_FORCE_PYQT=true
12+
# - PYTEST_VERSION=2.6.4 PYTEST_QT_FORCE_PYQT=false
13+
# - PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=true
14+
- PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=4
15+
- PYTEST_VERSION=2.7.0 PYTEST_QT_FORCE_PYQT=5
1516

1617
install:
18+
- sudo add-apt-repository --yes ppa:ubuntu-sdk-team/ppa
1719
- sudo apt-get update
1820

1921
# Qt

install-qt.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@ def run(cmd):
1212
sys.exit('command %s failed with status %s' % (cmd, r))
1313

1414
py3k = sys.version_info[0] == 3
15-
if os.environ['PYTEST_QT_FORCE_PYQT'] == "true":
15+
if os.environ['PYTEST_QT_FORCE_PYQT'] != "false":
16+
pyqt_ver = os.environ['PYTEST_QT_FORCE_PYQT']
17+
assert pyqt_ver in ('4', '5'), 'unexpected pyqt_version: %s' % pyqt_ver
1618
if py3k:
17-
run('sudo apt-get install -qq python3-pyqt4')
19+
run('sudo apt-get install -qq python3-pyqt%s' % pyqt_ver)
1820
else:
19-
run('sudo apt-get install -qq python-qt4')
21+
run('sudo apt-get install -qq python-qt%s' % pyqt_ver)
2022
else:
2123
if py3k:
2224
run('sudo apt-get install -qq python3-pyside')

pytestqt/_tests/test_basics.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,16 @@
11
import weakref
22
import pytest
3-
from pytestqt.qt_compat import QtGui, Qt, QEvent, QtCore
3+
from pytestqt.qt_compat import QtGui, Qt, QEvent, QtCore, QApplication, \
4+
QWidget
45

56

67
def test_basics(qtbot):
78
"""
89
Basic test that works more like a sanity check to ensure we are setting up a QApplication
910
properly and are able to display a simple event_recorder.
1011
"""
11-
assert isinstance(QtGui.qApp, QtGui.QApplication)
12-
widget = QtGui.QWidget()
12+
assert QApplication.instance() is not None
13+
widget = QWidget()
1314
qtbot.addWidget(widget)
1415
widget.setWindowTitle('W1')
1516
widget.show()
@@ -62,7 +63,7 @@ def test_stop_for_interaction(qtbot):
6263
"""
6364
Test qtbot.stopForInteraction()
6465
"""
65-
widget = QtGui.QWidget()
66+
widget = QWidget()
6667
qtbot.addWidget(widget)
6768
qtbot.waitForWindowShown(widget)
6869
QtCore.QTimer.singleShot(0, widget.close)
@@ -73,13 +74,13 @@ def test_widget_kept_as_weakref(qtbot):
7374
"""
7475
Test if the widget is kept as a weak reference in QtBot
7576
"""
76-
widget = QtGui.QWidget()
77+
widget = QWidget()
7778
qtbot.add_widget(widget)
7879
widget = weakref.ref(widget)
7980
assert widget() is None
8081

8182

82-
class EventRecorder(QtGui.QWidget):
83+
class EventRecorder(QWidget):
8384

8485
"""
8586
Widget that records some kind of events sent to it.
@@ -90,7 +91,7 @@ class EventRecorder(QtGui.QWidget):
9091
"""
9192

9293
def __init__(self):
93-
QtGui.QWidget.__init__(self)
94+
QWidget.__init__(self)
9495
self._event_types = {}
9596
self.event_data = None
9697

pytestqt/_tests/test_exceptions.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22
import sys
33
from pytestqt.plugin import capture_exceptions, format_captured_exceptions
4-
from pytestqt.qt_compat import QtGui, Qt, QtCore
4+
from pytestqt.qt_compat import QtGui, Qt, QtCore, QApplication
55

66

77
pytest_plugins = 'pytester'
@@ -31,7 +31,7 @@ def test_catch_exceptions_in_virtual_methods(qtbot, raise_error):
3131
tests fail if any.
3232
"""
3333
v = Receiver(raise_error)
34-
app = QtGui.QApplication.instance()
34+
app = QApplication.instance()
3535
app.sendEvent(v, QtCore.QEvent(QtCore.QEvent.User))
3636
app.sendEvent(v, QtCore.QEvent(QtCore.QEvent.User))
3737
app.processEvents()
@@ -67,9 +67,9 @@ def test_no_capture(testdir, no_capture_by_marker):
6767
''')
6868
testdir.makepyfile('''
6969
import pytest
70-
from pytestqt.qt_compat import QtGui, QtCore
70+
from pytestqt.qt_compat import QWidget, QtCore
7171
72-
class MyWidget(QtGui.QWidget):
72+
class MyWidget(QWidget):
7373
7474
def mouseReleaseEvent(self, ev):
7575
raise RuntimeError

pytestqt/plugin.py

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

77
import pytest
88

9-
from pytestqt.qt_compat import QtCore, QtGui, QtTest
9+
from pytestqt.qt_compat import QtCore, QtTest, QApplication
1010

1111

1212
def _inject_qtest_methods(cls):
@@ -370,9 +370,9 @@ def qapp():
370370
fixture that instantiates the QApplication instance that will be used by
371371
the tests.
372372
"""
373-
app = QtGui.QApplication.instance()
373+
app = QApplication.instance()
374374
if app is None:
375-
app = QtGui.QApplication([])
375+
app = QApplication([])
376376
yield app
377377
app.exit()
378378
else:

pytestqt/qt_compat.py

Lines changed: 30 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,36 +12,44 @@
1212

1313
if not on_rtd: # pragma: no cover
1414
try:
15-
import PySide.QtCore as _QtCore
16-
QtCore = _QtCore
15+
from PySide import QtCore
1716
USING_PYSIDE = True
1817
except ImportError:
1918
USING_PYSIDE = False
2019

21-
FORCE_PYQT = os.environ.get('PYTEST_QT_FORCE_PYQT', 'false') == 'true'
20+
FORCE_PYQT = os.environ.get('PYTEST_QT_FORCE_PYQT', 'false') != 'false'
21+
PYQT_VER = None
2222
if not USING_PYSIDE or FORCE_PYQT:
2323
try:
2424
import sip
2525
except ImportError:
2626
msg = 'pytest-qt requires either PyQt4 or PySide to be installed'
2727
raise ImportError(msg)
28+
29+
PYQT_VER = os.environ.get['PYTEST_QT_FORCE_PYQT']
30+
# backward compatibility
31+
if PYQT_VER == 'true':
32+
PYQT_VER = '4'
33+
if PYQT_VER not in ('4', '5'):
34+
raise RuntimeError('Unsupported PyQt version: %s' % PYQT_VER)
35+
2836
USING_PYSIDE = False
29-
import PyQt4.QtCore as _QtCore
30-
QtCore = _QtCore
3137

3238
if USING_PYSIDE:
33-
def _import_module(moduleName):
34-
pyside = __import__('PySide', globals(), locals(), [moduleName], 0)
35-
return getattr(pyside, moduleName)
39+
def _import_module(module_name):
40+
pyside = __import__('PySide', globals(), locals(), [module_name], 0)
41+
return getattr(pyside, module_name)
3642

3743
Signal = QtCore.Signal
3844
Slot = QtCore.Slot
3945
Property = QtCore.Property
4046
else:
41-
def _import_module(moduleName):
42-
pyside = __import__('PyQt4', globals(), locals(), [moduleName], 0)
43-
return getattr(pyside, moduleName)
44-
47+
def _import_module(module_name):
48+
pyside = __import__('PyQt%s' % PYQT_VER,
49+
globals(), locals(), [module_name], 0)
50+
return getattr(pyside, module_name)
51+
52+
QtCore = _import_module('QtCore')
4553
Signal = QtCore.pyqtSignal
4654
Slot = QtCore.pyqtSlot
4755
Property = QtCore.pyqtProperty
@@ -51,7 +59,14 @@ def _import_module(moduleName):
5159
QtTest = _import_module('QtTest')
5260
Qt = QtCore.Qt
5361
QEvent = QtCore.QEvent
54-
62+
if not USING_PYSIDE and PYQT_VER == '5':
63+
_QtWidgets = _import_module('QtWidgets')
64+
QApplication = _QtWidgets.QApplication
65+
QWidget = _QtWidgets.QWidget
66+
else:
67+
QApplication = QtGui.QApplication
68+
QWidget = QtGui.QWidget
69+
5570
else: # pragma: no cover
5671
USING_PYSIDE = True
5772

@@ -77,3 +92,5 @@ def __getattr__(cls, name):
7792
QtTest = Mock()
7893
Qt = Mock()
7994
QEvent = Mock()
95+
QApplication = Mock()
96+
QWidget = Mock()

0 commit comments

Comments
 (0)