Bugfixes:
- GraphicsView.render now correctly invokes GraphicsScene.prepareForPaint - Fixed RemoteGraphicsView renderer to use new PyQt QImage API. - multiprocess.Process now pipes stdout/err directly to console when in debugging mode
This commit is contained in:
parent
ea8079334f
commit
31928e70a5
@ -13,7 +13,8 @@ from pyqtgraph.widgets.RemoteGraphicsView import RemoteGraphicsView
|
||||
app = pg.mkQApp()
|
||||
|
||||
## Create the widget
|
||||
v = RemoteGraphicsView(debug=False)
|
||||
v = RemoteGraphicsView(debug=False) # setting debug=True causes both processes to print information
|
||||
# about interprocess communication
|
||||
v.show()
|
||||
v.setWindowTitle('pyqtgraph example: RemoteGraphicsView')
|
||||
|
||||
|
@ -311,13 +311,15 @@ def image(*args, **kargs):
|
||||
return w
|
||||
show = image ## for backward compatibility
|
||||
|
||||
def dbg():
|
||||
def dbg(*args, **kwds):
|
||||
"""
|
||||
Create a console window and begin watching for exceptions.
|
||||
|
||||
All arguments are passed to :func:`ConsoleWidget.__init__() <pyqtgraph.console.ConsoleWidget.__init__>`.
|
||||
"""
|
||||
mkQApp()
|
||||
from . import console
|
||||
c = console.ConsoleWidget()
|
||||
c = console.ConsoleWidget(*args, **kwds)
|
||||
c.catchAllExceptions()
|
||||
c.show()
|
||||
global consoles
|
||||
|
@ -20,10 +20,8 @@ if __name__ == '__main__':
|
||||
|
||||
if opts.pop('pyside', False):
|
||||
import PySide
|
||||
#import pyqtgraph
|
||||
#import pyqtgraph.multiprocess.processes
|
||||
|
||||
targetStr = opts.pop('targetStr')
|
||||
target = pickle.loads(targetStr) ## unpickling the target should import everything we need
|
||||
#target(name, port, authkey, ppid)
|
||||
target(**opts) ## Send all other options to the target function
|
||||
sys.exit(0)
|
||||
|
@ -48,9 +48,10 @@ class Process(RemoteEventHandler):
|
||||
it must be picklable (bound methods are not).
|
||||
copySysPath If True, copy the contents of sys.path to the remote process
|
||||
debug If True, print detailed information about communication
|
||||
with the child process.
|
||||
with the child process. Note that this option may cause
|
||||
strange behavior on some systems due to a python bug:
|
||||
http://bugs.python.org/issue3905
|
||||
============ =============================================================
|
||||
|
||||
"""
|
||||
if target is None:
|
||||
target = startEventLoop
|
||||
@ -81,8 +82,14 @@ class Process(RemoteEventHandler):
|
||||
self.debugMsg('Starting child process (%s %s)' % (executable, bootstrap))
|
||||
|
||||
## note: we need all three streams to have their own PIPE due to this bug:
|
||||
## http://bugs.python.org/issue3905
|
||||
self.proc = subprocess.Popen((executable, bootstrap), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
## http://bugs.python.org/issue3905
|
||||
if debug is True: # when debugging, we need to keep the usual stdout
|
||||
stdout = sys.stdout
|
||||
stderr = sys.stderr
|
||||
else:
|
||||
stdout = subprocess.PIPE
|
||||
stderr = subprocess.PIPE
|
||||
self.proc = subprocess.Popen((executable, bootstrap), stdin=subprocess.PIPE, stdout=stdout, stderr=stderr)
|
||||
|
||||
targetStr = pickle.dumps(target) ## double-pickle target so that child has a chance to
|
||||
## set its sys.path properly before unpickling the target
|
||||
|
@ -147,6 +147,11 @@ class GraphicsView(QtGui.QGraphicsView):
|
||||
#print "GV: paint", ev.rect()
|
||||
return QtGui.QGraphicsView.paintEvent(self, ev)
|
||||
|
||||
def render(self, *args, **kwds):
|
||||
self.scene().prepareForPaint()
|
||||
return QtGui.QGraphicsView.render(self, *args, **kwds)
|
||||
|
||||
|
||||
def close(self):
|
||||
self.centralWidget = None
|
||||
self.scene().clear()
|
||||
|
@ -18,12 +18,15 @@ class RemoteGraphicsView(QtGui.QWidget):
|
||||
|
||||
"""
|
||||
def __init__(self, parent=None, *args, **kwds):
|
||||
"""
|
||||
The keyword arguments 'debug' and 'name', if specified, are passed to QtProcess.__init__().
|
||||
"""
|
||||
self._img = None
|
||||
self._imgReq = None
|
||||
self._sizeHint = (640,480) ## no clue why this is needed, but it seems to be the default sizeHint for GraphicsView.
|
||||
## without it, the widget will not compete for space against another GraphicsView.
|
||||
QtGui.QWidget.__init__(self)
|
||||
self._proc = mp.QtProcess(debug=kwds.pop('debug', False))
|
||||
self._proc = mp.QtProcess(debug=kwds.pop('debug', False), name=kwds.pop('name', None))
|
||||
self.pg = self._proc._import('pyqtgraph')
|
||||
self.pg.setConfigOptions(**self.pg.CONFIG_OPTIONS)
|
||||
rpgRemote = self._proc._import('pyqtgraph.widgets.RemoteGraphicsView')
|
||||
@ -123,6 +126,7 @@ class Renderer(GraphicsView):
|
||||
|
||||
def __init__(self, *args, **kwds):
|
||||
## Create shared memory for rendered image
|
||||
#pg.dbg(namespace={'r': self})
|
||||
if sys.platform.startswith('win'):
|
||||
self.shmtag = "pyqtgraph_shmem_" + ''.join([chr((random.getrandbits(20)%25) + 97) for i in range(20)])
|
||||
self.shm = mmap.mmap(-1, mmap.PAGESIZE, self.shmtag) # use anonymous mmap on windows
|
||||
@ -184,7 +188,11 @@ class Renderer(GraphicsView):
|
||||
self.img = QtGui.QImage(ch, self.width(), self.height(), QtGui.QImage.Format_ARGB32)
|
||||
else:
|
||||
address = ctypes.addressof(ctypes.c_char.from_buffer(self.shm, 0))
|
||||
self.img = QtGui.QImage(sip.voidptr(address), self.width(), self.height(), QtGui.QImage.Format_ARGB32)
|
||||
try:
|
||||
self.img = QtGui.QImage(sip.voidptr(address), self.width(), self.height(), QtGui.QImage.Format_ARGB32)
|
||||
except TypeError:
|
||||
# different versions of pyqt have different requirements here..
|
||||
self.img = QtGui.QImage(memoryview(buffer(self.shm)), self.width(), self.height(), QtGui.QImage.Format_ARGB32)
|
||||
self.img.fill(0xffffffff)
|
||||
p = QtGui.QPainter(self.img)
|
||||
self.render(p, self.viewRect(), self.rect())
|
||||
|
Loading…
Reference in New Issue
Block a user