@@ -155,6 +155,68 @@ ensuring the results are correct::
155
155
assert_application_results(app)
156
156
157
157
158
+ Exceptions in virtual methods
159
+ =============================
160
+
161
+ It is common in Qt programming to override virtual C++ methods to customize
162
+ behavior, like listening for mouse events, implement drawing routines, etc.
163
+
164
+ Fortunately, both ``PyQt `` and ``PySide `` support overriding this virtual methods
165
+ naturally in your python code::
166
+
167
+ class MyWidget(QWidget):
168
+
169
+ # mouseReleaseEvent
170
+ def mouseReleaseEvent(self, ev):
171
+ print('mouse released at: %s' % ev.pos())
172
+
173
+ This works fine, but if python code in Qt virtual methods raise an exception
174
+ ``PyQt `` and ``PySide `` will just print the exception traceback to standard
175
+ error, since this method is called deep within Qt's even loop handling and
176
+ exceptions are not allowed at that point.
177
+
178
+ This might be surprising for python users which are used to exceptions
179
+ being raised at the calling point: for example, the following code will just
180
+ print a stack trace without raising any exception::
181
+
182
+ class MyWidget(QWidget):
183
+
184
+ def mouseReleaseEvent(self, ev):
185
+ raise RuntimeError('unexpected error')
186
+
187
+ w = MyWidget()
188
+ QTest.mouseClick(w, QtCore.Qt.LeftButton)
189
+
190
+
191
+ To make testing Qt code less surprising, ``pytest-qt `` automatically
192
+ installs an exception hook which captures errors and fails tests when exceptions
193
+ are raised inside virtual methods, like this::
194
+
195
+ E Failed: Qt exceptions in virtual methods:
196
+ E ________________________________________________________________________________
197
+ E File "x:\pytest-qt\pytestqt\_tests\test_exceptions.py", line 14, in event
198
+ E raise RuntimeError('unexpected error')
199
+ E
200
+ E RuntimeError: unexpected error
201
+
202
+
203
+ Disabling the automatic exception hook
204
+ --------------------------------------
205
+
206
+ You can disable the automatic exception hook on individual tests by using a
207
+ ``qt_no_exception_capture `` marker::
208
+
209
+ @pytest.mark.qt_no_exception_capture
210
+ def test_buttons(qtbot):
211
+ ...
212
+
213
+ Or even disable it for your entire project in your ``pytest.ini `` file::
214
+
215
+ [pytest]
216
+ qt_no_exception_capture = 1
217
+
218
+ This might be desirable if you plan to install a custom exception hook.
219
+
158
220
QtBot
159
221
=====
160
222
0 commit comments