Merge pull request #1605 from pijyoi/clean_shutdown

let examples have a chance to exit normally
This commit is contained in:
Ogi Moore 2021-03-06 20:18:50 -08:00 committed by GitHub
commit c5a1174f04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 64 additions and 107 deletions

View File

@ -36,6 +36,10 @@ i = 0
updateTime = ptime.time() updateTime = ptime.time()
fps = 0 fps = 0
timer = QtCore.QTimer()
timer.setSingleShot(True)
# not using QTimer.singleShot() because of persistence on PyQt. see PR #1605
def updateData(): def updateData():
global img, data, i, updateTime, fps global img, data, i, updateTime, fps
@ -43,7 +47,7 @@ def updateData():
img.setImage(data[i]) img.setImage(data[i])
i = (i+1) % data.shape[0] i = (i+1) % data.shape[0]
QtCore.QTimer.singleShot(1, updateData) timer.start(1)
now = ptime.time() now = ptime.time()
fps2 = 1.0 / (now-updateTime) fps2 = 1.0 / (now-updateTime)
updateTime = now updateTime = now
@ -51,7 +55,7 @@ def updateData():
#print "%0.1f fps" % fps #print "%0.1f fps" % fps
timer.timeout.connect(updateData)
updateData() updateData()
## Start Qt event loop unless running in interactive mode. ## Start Qt event loop unless running in interactive mode.

View File

@ -61,6 +61,10 @@ wave_speed = 0.3
wave_length = 10 wave_length = 10
color_speed = 0.3 color_speed = 0.3
timer = QtCore.QTimer()
timer.setSingleShot(True)
# not using QTimer.singleShot() because of persistence on PyQt. see PR #1605
i=0 i=0
def updateData(): def updateData():
global i global i
@ -74,8 +78,9 @@ def updateData():
new_z) new_z)
i += wave_speed i += wave_speed
QtCore.QTimer.singleShot(1000//fps, updateData) timer.start(1000//fps)
timer.timeout.connect(updateData)
updateData() updateData()
## Start Qt event loop unless running in interactive mode. ## Start Qt event loop unless running in interactive mode.

View File

@ -56,12 +56,15 @@ installedFrontends = sorted([
frontend for frontend, isPresent in frontends.items() if isPresent 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"]) exceptionCondition = namedtuple("exceptionCondition", ["condition", "reason"])
conditionalExamples = { 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( "hdf5.py": exceptionCondition(
False, False,
reason="Example requires user interaction" reason="Example requires user interaction"
@ -71,104 +74,44 @@ conditionalExamples = {
reason="Test is being problematic on CI machines" reason="Test is being problematic on CI machines"
), ),
'GLVolumeItem.py': exceptionCondition( 'GLVolumeItem.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLIsosurface.py': exceptionCondition( 'GLIsosurface.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLSurfacePlot.py': exceptionCondition( 'GLSurfacePlot.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLScatterPlotItem.py': exceptionCondition( 'GLScatterPlotItem.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLshaders.py': exceptionCondition( 'GLshaders.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLLinePlotItem.py': exceptionCondition( 'GLLinePlotItem.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLMeshItem.py': exceptionCondition( 'GLMeshItem.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLImageItem.py': exceptionCondition( 'GLImageItem.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLBarGraphItem.py': exceptionCondition( 'GLBarGraphItem.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
), ),
'GLViewWidget.py': exceptionCondition( 'GLViewWidget.py': exceptionCondition(
not(platform.system() == "Darwin" and not darwin_opengl_broken,
tuple(map(int, platform.mac_ver()[0].split("."))) >= (10, 16) and reason=darwin_opengl_reason
(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"
)
) )
} }
@ -212,22 +155,23 @@ def testExamples(frontend, f):
import2 = os.path.splitext(os.path.split(fn)[1])[0] import2 = os.path.splitext(os.path.split(fn)[1])[0]
code = """ code = """
try: try:
%s {0}
import initExample import initExample
import pyqtgraph as pg import pyqtgraph as pg
import %s import {1}
import sys import sys
print("test complete") print("test complete")
sys.stdout.flush() sys.stdout.flush()
import time pg.Qt.QtCore.QTimer.singleShot(1000, pg.Qt.QtWidgets.QApplication.quit)
while True: ## run a little event loop pg.Qt.QtWidgets.QApplication.instance().exec_()
pg.QtGui.QApplication.processEvents() names = [x for x in dir({1}) if not x.startswith('_')]
time.sleep(0.01) for name in names:
delattr({1}, name)
except: except:
print("test failed") print("test failed")
raise raise
""" % (import1, import2) """.format(import1, import2)
if sys.platform.startswith('win'): if sys.platform.startswith('win'):
process = subprocess.Popen([sys.executable], process = subprocess.Popen([sys.executable],
stdin=subprocess.PIPE, stdin=subprocess.PIPE,
@ -259,8 +203,13 @@ except:
if output.endswith('test failed'): if output.endswith('test failed'):
fail = True fail = True
break break
time.sleep(1) start = time.time()
process.kill() 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.communicate()
res = (process.stdout.read(), process.stderr.read()) res = (process.stdout.read(), process.stderr.read())
if (fail or if (fail or

View File

@ -390,16 +390,8 @@ if m is not None and list(map(int, m.groups())) < versionReq:
print(list(map(int, m.groups()))) print(list(map(int, m.groups())))
raise Exception('pyqtgraph requires Qt version >= %d.%d (your version is %s)' % (versionReq[0], versionReq[1], QtVersion)) raise Exception('pyqtgraph requires Qt version >= %d.%d (your version is %s)' % (versionReq[0], versionReq[1], QtVersion))
class App(QtGui.QApplication): App = QtWidgets.QApplication
# subclassing QApplication causes segfaults on PySide{2, 6} / Python 3.8.7+
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")
QAPP = None QAPP = None
def mkQApp(name=None): def mkQApp(name=None):
@ -413,6 +405,11 @@ def mkQApp(name=None):
""" """
global QAPP global QAPP
def onPaletteChange(palette):
color = palette.base().color().name()
app = QtWidgets.QApplication.instance()
app.setProperty('darkMode', color.lower() != "#ffffff")
QAPP = QtGui.QApplication.instance() QAPP = QtGui.QApplication.instance()
if QAPP is None: if QAPP is None:
# hidpi handling # hidpi handling
@ -426,7 +423,9 @@ def mkQApp(name=None):
else: # qt 5.12 and 5.13 else: # qt 5.12 and 5.13
QtGui.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling) QtGui.QApplication.setAttribute(QtCore.Qt.AA_EnableHighDpiScaling)
QtGui.QApplication.setAttribute(QtCore.Qt.AA_UseHighDpiPixmaps) 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: if name is not None:
QAPP.setApplicationName(name) QAPP.setApplicationName(name)