diff --git a/examples/ImageItem.py b/examples/ImageItem.py index 9982d65c..49141084 100644 --- a/examples/ImageItem.py +++ b/examples/ImageItem.py @@ -36,6 +36,10 @@ i = 0 updateTime = ptime.time() fps = 0 +timer = QtCore.QTimer() +timer.setSingleShot(True) +# not using QTimer.singleShot() because of persistence on PyQt. see PR #1605 + def updateData(): global img, data, i, updateTime, fps @@ -43,7 +47,7 @@ def updateData(): img.setImage(data[i]) i = (i+1) % data.shape[0] - QtCore.QTimer.singleShot(1, updateData) + timer.start(1) now = ptime.time() fps2 = 1.0 / (now-updateTime) updateTime = now @@ -51,7 +55,7 @@ def updateData(): #print "%0.1f fps" % fps - +timer.timeout.connect(updateData) updateData() ## Start Qt event loop unless running in interactive mode. diff --git a/examples/PColorMeshItem.py b/examples/PColorMeshItem.py index 1e5f4e85..44604c8e 100644 --- a/examples/PColorMeshItem.py +++ b/examples/PColorMeshItem.py @@ -61,6 +61,10 @@ wave_speed = 0.3 wave_length = 10 color_speed = 0.3 +timer = QtCore.QTimer() +timer.setSingleShot(True) +# not using QTimer.singleShot() because of persistence on PyQt. see PR #1605 + i=0 def updateData(): global i @@ -74,8 +78,9 @@ def updateData(): new_z) i += wave_speed - QtCore.QTimer.singleShot(1000//fps, updateData) + timer.start(1000//fps) +timer.timeout.connect(updateData) updateData() ## Start Qt event loop unless running in interactive mode. diff --git a/examples/test_examples.py b/examples/test_examples.py index ba1037ad..4339875c 100644 --- a/examples/test_examples.py +++ b/examples/test_examples.py @@ -56,12 +56,15 @@ installedFrontends = sorted([ frontend for frontend, isPresent in frontends.items() if isPresent ]) +darwin_opengl_broken = (platform.system() == "Darwin" and + tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and + (sys.version_info <= (3, 8, 7) or (3, 9) <= sys.version_info < (3, 9, 1))) + +darwin_opengl_reason = ("pyopenGL cannot find openGL library on big sur: " + "https://github.com/python/cpython/pull/21241") + exceptionCondition = namedtuple("exceptionCondition", ["condition", "reason"]) conditionalExamples = { - "test_ExampleApp.py": exceptionCondition( - not(platform.system() == "Linux" and frontends[Qt.PYSIDE2]), - reason="Unexplained, intermittent segfault and subsequent timeout on CI" - ), "hdf5.py": exceptionCondition( False, reason="Example requires user interaction" @@ -71,104 +74,44 @@ conditionalExamples = { reason="Test is being problematic on CI machines" ), 'GLVolumeItem.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLIsosurface.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLSurfacePlot.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLScatterPlotItem.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLshaders.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLLinePlotItem.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLMeshItem.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLImageItem.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLBarGraphItem.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ), 'GLViewWidget.py': exceptionCondition( - not(platform.system() == "Darwin" and - tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and - (sys.version_info <= (3, 8, 7) or - (sys.version_info >= (3, 9) and sys.version_info < (3, 9, 1)))), - reason=( - "pyopenGL cannot find openGL libray on big sur: " - "https://github.com/python/cpython/pull/21241" - ) + not darwin_opengl_broken, + reason=darwin_opengl_reason ) } @@ -212,22 +155,23 @@ def testExamples(frontend, f): import2 = os.path.splitext(os.path.split(fn)[1])[0] code = """ try: - %s + {0} import initExample import pyqtgraph as pg - import %s + import {1} import sys print("test complete") sys.stdout.flush() - import time - while True: ## run a little event loop - pg.QtGui.QApplication.processEvents() - time.sleep(0.01) + pg.Qt.QtCore.QTimer.singleShot(1000, pg.Qt.QtWidgets.QApplication.quit) + pg.Qt.QtWidgets.QApplication.instance().exec_() + names = [x for x in dir({1}) if not x.startswith('_')] + for name in names: + delattr({1}, name) except: print("test failed") raise -""" % (import1, import2) +""".format(import1, import2) if sys.platform.startswith('win'): process = subprocess.Popen([sys.executable], stdin=subprocess.PIPE, @@ -259,8 +203,13 @@ except: if output.endswith('test failed'): fail = True break - time.sleep(1) - process.kill() + start = time.time() + killed = False + while process.poll() is None: + time.sleep(0.1) + if time.time() - start > 2.0 and not killed: + process.kill() + killed = True #res = process.communicate() res = (process.stdout.read(), process.stderr.read()) if (fail or diff --git a/pyqtgraph/Qt.py b/pyqtgraph/Qt.py index 6d15a578..4c2e4502 100644 --- a/pyqtgraph/Qt.py +++ b/pyqtgraph/Qt.py @@ -390,16 +390,8 @@ if m is not None and list(map(int, m.groups())) < versionReq: print(list(map(int, m.groups()))) raise Exception('pyqtgraph requires Qt version >= %d.%d (your version is %s)' % (versionReq[0], versionReq[1], QtVersion)) -class App(QtGui.QApplication): - - def __init__(self, *args, **kwargs): - super(App, self).__init__(*args, **kwargs) - self.paletteChanged.connect(self.onPaletteChange) - self.onPaletteChange(self.palette()) - - def onPaletteChange(self, palette): - color = palette.base().color().name() - self.setProperty('darkMode', color.lower() != "#ffffff") +App = QtWidgets.QApplication +# subclassing QApplication causes segfaults on PySide{2, 6} / Python 3.8.7+ QAPP = None def mkQApp(name=None): @@ -413,6 +405,11 @@ def mkQApp(name=None): """ global QAPP + def onPaletteChange(palette): + color = palette.base().color().name() + app = QtWidgets.QApplication.instance() + app.setProperty('darkMode', color.lower() != "#ffffff") + QAPP = QtGui.QApplication.instance() if QAPP is None: # hidpi handling @@ -426,7 +423,9 @@ def mkQApp(name=None): else: # qt 5.12 and 5.13 QtGui.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) QtGui.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps) - QAPP = App(sys.argv or ["pyqtgraph"]) + QAPP = QtGui.QApplication(sys.argv or ["pyqtgraph"]) + QAPP.paletteChanged.connect(onPaletteChange) + QAPP.paletteChanged.emit(QAPP.palette()) if name is not None: QAPP.setApplicationName(name)