fix RemoteSpeedTest shutdown errors
fix BufferError: cannot close exported pointers exist for some reason, even though the ctypes object falls out of function scope, it causes a lingering reference. in any case, the use of ctypes is no longer necessary. Don't change temporary files mid-way for Darwin This fixes the CI issues on Darwin. close the remote process on app shutdown.
This commit is contained in:
parent
b54aa3914d
commit
2f4ceee1ce
@ -24,6 +24,8 @@ pg.setConfigOptions(antialias=True) ## this will be expensive for the local plo
|
|||||||
view.pg.setConfigOptions(antialias=True) ## prettier plots at no cost to the main process!
|
view.pg.setConfigOptions(antialias=True) ## prettier plots at no cost to the main process!
|
||||||
view.setWindowTitle('pyqtgraph example: RemoteSpeedTest')
|
view.setWindowTitle('pyqtgraph example: RemoteSpeedTest')
|
||||||
|
|
||||||
|
app.aboutToQuit.connect(view.close)
|
||||||
|
|
||||||
label = QtGui.QLabel()
|
label = QtGui.QLabel()
|
||||||
rcheck = QtGui.QCheckBox('plot remote')
|
rcheck = QtGui.QCheckBox('plot remote')
|
||||||
rcheck.setChecked(True)
|
rcheck.setChecked(True)
|
||||||
|
@ -70,10 +70,6 @@ conditionalExamples = {
|
|||||||
False,
|
False,
|
||||||
reason="Test is being problematic on CI machines"
|
reason="Test is being problematic on CI machines"
|
||||||
),
|
),
|
||||||
"RemoteGraphicsView.py": exceptionCondition(
|
|
||||||
not(platform.system() == "Darwin"),
|
|
||||||
reason="FileNotFoundError for pyqtgraph_shmem_* file"
|
|
||||||
),
|
|
||||||
"ProgressDialog.py": exceptionCondition(
|
"ProgressDialog.py": exceptionCondition(
|
||||||
not(platform.system() == "Linux"),
|
not(platform.system() == "Linux"),
|
||||||
reason="QXcbConnection: XCB error"
|
reason="QXcbConnection: XCB error"
|
||||||
|
@ -5,7 +5,7 @@ from .. import multiprocess as mp
|
|||||||
from .GraphicsView import GraphicsView
|
from .GraphicsView import GraphicsView
|
||||||
from .. import CONFIG_OPTIONS
|
from .. import CONFIG_OPTIONS
|
||||||
import numpy as np
|
import numpy as np
|
||||||
import mmap, tempfile, ctypes, atexit, sys, random
|
import mmap, tempfile, os, atexit, sys, random
|
||||||
|
|
||||||
__all__ = ['RemoteGraphicsView']
|
__all__ = ['RemoteGraphicsView']
|
||||||
|
|
||||||
@ -78,10 +78,6 @@ class RemoteGraphicsView(QtGui.QWidget):
|
|||||||
if sys.platform.startswith('win'):
|
if sys.platform.startswith('win'):
|
||||||
self.shmtag = newfile ## on windows, we create a new tag for every resize
|
self.shmtag = newfile ## on windows, we create a new tag for every resize
|
||||||
self.shm = mmap.mmap(-1, size, self.shmtag) ## can't use tmpfile on windows because the file can only be opened once.
|
self.shm = mmap.mmap(-1, size, self.shmtag) ## can't use tmpfile on windows because the file can only be opened once.
|
||||||
elif sys.platform == 'darwin':
|
|
||||||
self.shmFile.close()
|
|
||||||
self.shmFile = open(self._view.shmFileName(), 'r')
|
|
||||||
self.shm = mmap.mmap(self.shmFile.fileno(), size, mmap.MAP_SHARED, mmap.PROT_READ)
|
|
||||||
else:
|
else:
|
||||||
self.shm = mmap.mmap(self.shmFile.fileno(), size, mmap.MAP_SHARED, mmap.PROT_READ)
|
self.shm = mmap.mmap(self.shmFile.fileno(), size, mmap.MAP_SHARED, mmap.PROT_READ)
|
||||||
self.shm.seek(0)
|
self.shm.seek(0)
|
||||||
@ -159,6 +155,7 @@ class RemoteGraphicsView(QtGui.QWidget):
|
|||||||
|
|
||||||
def close(self):
|
def close(self):
|
||||||
"""Close the remote process. After this call, the widget will no longer be updated."""
|
"""Close the remote process. After this call, the widget will no longer be updated."""
|
||||||
|
self._view.sceneRendered.disconnect()
|
||||||
self._proc.close()
|
self._proc.close()
|
||||||
|
|
||||||
|
|
||||||
@ -224,25 +221,20 @@ class Renderer(GraphicsView):
|
|||||||
self.shm = mmap.mmap(-1, size, self.shmtag)
|
self.shm = mmap.mmap(-1, size, self.shmtag)
|
||||||
elif sys.platform == 'darwin':
|
elif sys.platform == 'darwin':
|
||||||
self.shm.close()
|
self.shm.close()
|
||||||
self.shmFile.close()
|
fd = self.shmFile.fileno()
|
||||||
self.shmFile = tempfile.NamedTemporaryFile(prefix='pyqtgraph_shmem_')
|
os.ftruncate(fd, size + 1)
|
||||||
self.shmFile.write(b'\x00' * (size + 1))
|
self.shm = mmap.mmap(fd, size, mmap.MAP_SHARED, mmap.PROT_WRITE)
|
||||||
self.shmFile.flush()
|
|
||||||
self.shm = mmap.mmap(self.shmFile.fileno(), size, mmap.MAP_SHARED, mmap.PROT_WRITE)
|
|
||||||
else:
|
else:
|
||||||
self.shm.resize(size)
|
self.shm.resize(size)
|
||||||
|
|
||||||
## render the scene directly to shared memory
|
## render the scene directly to shared memory
|
||||||
ctypes_obj = ctypes.c_char.from_buffer(self.shm, 0)
|
if QT_LIB == 'PyQt5':
|
||||||
if QT_LIB.startswith('PySide'):
|
img_ptr = int(sip.voidptr(self.shm))
|
||||||
# PySide2, PySide6
|
elif QT_LIB == 'PyQt6':
|
||||||
img_ptr = ctypes_obj
|
img_ptr = sip.voidptr(self.shm)
|
||||||
else:
|
else:
|
||||||
# PyQt5, PyQt6
|
# PySide2, PySide6
|
||||||
img_ptr = sip.voidptr(ctypes.addressof(ctypes_obj))
|
img_ptr = self.shm
|
||||||
|
|
||||||
if QT_LIB == 'PyQt6':
|
|
||||||
img_ptr.setsize(size)
|
|
||||||
|
|
||||||
self.img = QtGui.QImage(img_ptr, self.width(), self.height(), QtGui.QImage.Format_ARGB32)
|
self.img = QtGui.QImage(img_ptr, self.width(), self.height(), QtGui.QImage.Format_ARGB32)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user