Fix BusyCursor to use internal stack provided by setOverrideCursor/restoreOverrideCursor (#1827)

* un-busy as many times as needed

* lint

* add test to prove cursor behavior

* tentative change in the hopes that all supported qt versions behave properly

* remove unnecessary code

* use contextmanager decorator instead of class

* use full path to WaitCursor

* restore docstring; refactor variable for clarity

* fix docstring whitespace

* break up long lines

* use variable to shorten instead
This commit is contained in:
Martin Chase 2021-06-09 13:32:24 -07:00 committed by GitHub
parent 6f0ffcbf8f
commit 2fb04b754c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 33 additions and 27 deletions

View File

@ -1,35 +1,28 @@
from ..Qt import QtGui, QtCore, QT_LIB # -*- coding: utf-8 -*-
from contextlib import contextmanager
__all__ = ['BusyCursor'] from ..Qt import QtGui, QtCore
class BusyCursor(object): __all__ = ["BusyCursor"]
"""Class for displaying a busy mouse cursor during long operations.
@contextmanager
def BusyCursor():
"""
Display a busy mouse cursor during long operations.
Usage:: Usage::
with pyqtgraph.BusyCursor(): with BusyCursor():
doLongOperation() doLongOperation()
May be nested. If called from a non-gui thread, then the cursor will not be affected. May be nested. If called from a non-gui thread, then the cursor will not be affected.
""" """
active = [] app = QtCore.QCoreApplication.instance()
in_gui_thread = (app is not None) and (QtCore.QThread.currentThread() == app.thread())
def __enter__(self): try:
app = QtCore.QCoreApplication.instance() if in_gui_thread:
isGuiThread = (app is not None) and (QtCore.QThread.currentThread() == app.thread()) QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CursorShape.WaitCursor))
if isGuiThread and QtGui.QApplication.instance() is not None: yield
if QT_LIB == 'PySide': finally:
# pass CursorShape rather than QCursor for PySide if in_gui_thread:
# see https://bugreports.qt.io/browse/PYSIDE-243 QtGui.QApplication.restoreOverrideCursor()
QtGui.QApplication.setOverrideCursor(QtCore.Qt.CursorShape.WaitCursor)
else:
QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CursorShape.WaitCursor))
BusyCursor.active.append(self)
self._active = True
else:
self._active = False
def __exit__(self, *args):
if self._active:
BusyCursor.active.pop(-1)
if len(BusyCursor.active) == 0:
QtGui.QApplication.restoreOverrideCursor()

View File

@ -0,0 +1,13 @@
# -*- coding: utf-8 -*-
import pyqtgraph as pg
pg.mkQApp()
def test_nested_busy_cursors_clear_after_all_exit():
with pg.BusyCursor():
wait_cursor = pg.Qt.QtCore.Qt.CursorShape.WaitCursor
with pg.BusyCursor():
assert pg.Qt.QtGui.QApplication.overrideCursor().shape() == wait_cursor, "Cursor should be waiting"
assert pg.Qt.QtGui.QApplication.overrideCursor().shape() == wait_cursor, "Cursor should be waiting"
assert pg.Qt.QtGui.QApplication.overrideCursor() is None, "No override cursor should be set"