Skip to content

QApplication.processEvents() blocks qtbot on MacOS #284

Open
@impact27

Description

@impact27

If qtbot tries to stop waiting while QApplication.processEvents() is being called, the test will hang indefinitely.
What happens is that:

  • qtbot creates a QEventLoop
  • an event calling QApplication.processEvents() is processed by QEventLoop
  • The qtbot timer event that calls _quit_loop_by_timeout is processed by QApplication.processEvents()
  • Somehow self._loop.quit() doesn't quit the loop if it is called from QApplication.processEvents()

Code to reproduce (save as test_qtbot.py):

import pytest
import time
from PyQt5.QtWidgets import QApplication, QWidget
from PyQt5.QtCore import QEventLoop, QTimer


class MyWidget(QWidget):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._timer = QTimer(self)
        self._timer.setSingleShot(True)
        self._timer.setInterval(10)
        self._timer.timeout.connect(self._wait_process_events)
        self._timer.start()

    def _wait_process_events(self):
        time.sleep(1)
        QApplication.processEvents()


def test_qtbot(qtbot):
    """
    qtbot does the following:
    1. start QEventLoop
    2. process an event that calls QApplication.processEvents()
    3. this processes an event that calls loop.quit()
        which doesn't quit the wait loop
    """
    widget = MyWidget()
    qtbot.addWidget(widget)
    widget.show()
    qtbot.wait(500)

if __name__ == "__main__":
    pytest.main()

Versions I am using:

PyQt5                                   5.12.3
pytest                                  5.3.1         
pytest-qt                               3.2.2  

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions