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):
"""Class for displaying a busy mouse cursor during long operations.
__all__ = ["BusyCursor"]
@contextmanager
def BusyCursor():
"""
Display a busy mouse cursor during long operations.
Usage::
with pyqtgraph.BusyCursor():
with BusyCursor():
doLongOperation()
May be nested. If called from a non-gui thread, then the cursor will not be affected.
"""
active = []
def __enter__(self):
app = QtCore.QCoreApplication.instance()
isGuiThread = (app is not None) and (QtCore.QThread.currentThread() == app.thread())
if isGuiThread and QtGui.QApplication.instance() is not None:
if QT_LIB == 'PySide':
# pass CursorShape rather than QCursor for PySide
# see https://bugreports.qt.io/browse/PYSIDE-243
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()
app = QtCore.QCoreApplication.instance()
in_gui_thread = (app is not None) and (QtCore.QThread.currentThread() == app.thread())
try:
if in_gui_thread:
QtGui.QApplication.setOverrideCursor(QtGui.QCursor(QtCore.Qt.CursorShape.WaitCursor))
yield
finally:
if in_gui_thread:
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"