Fixed RemoteGraphicsView on windows

- Avoid using authkey on windows; seems to be broken
 - Included yet another method of accessing shared memory as QImage
This commit is contained in:
Luke Campagnola 2013-11-17 09:27:55 -07:00
parent 1e82104986
commit 08be09ee40
3 changed files with 28 additions and 12 deletions

View File

@ -35,7 +35,7 @@ class Process(RemoteEventHandler):
ProxyObject for more information.
"""
def __init__(self, name=None, target=None, executable=None, copySysPath=True, debug=False):
def __init__(self, name=None, target=None, executable=None, copySysPath=True, debug=False, timeout=20):
"""
============ =============================================================
Arguments:
@ -63,19 +63,23 @@ class Process(RemoteEventHandler):
## random authentication key
authkey = os.urandom(20)
## Windows seems to have a hard time with hmac
if sys.platform.startswith('win'):
authkey = None
#print "key:", ' '.join([str(ord(x)) for x in authkey])
## Listen for connection from remote process (and find free port number)
port = 10000
while True:
try:
## hmac authentication appears to be broken on windows (says AuthenticationError: digest received was wrong)
l = multiprocessing.connection.Listener(('localhost', int(port)), authkey=authkey)
break
except socket.error as ex:
if ex.errno != 98:
raise
port += 1
## start remote process, instruct it to run target function
sysPath = sys.path if copySysPath else None
bootstrap = os.path.abspath(os.path.join(os.path.dirname(__file__), 'bootstrap.py'))
@ -111,7 +115,7 @@ class Process(RemoteEventHandler):
self.proc.stdin.close()
## open connection for remote process
self.debugMsg('Listening for child process..')
self.debugMsg('Listening for child process on port %d, authkey=%s..' % (port, repr(authkey)))
while True:
try:
conn = l.accept()
@ -140,7 +144,12 @@ class Process(RemoteEventHandler):
def startEventLoop(name, port, authkey, ppid, debug=False):
if debug:
import os
print('[%d] connecting to server at port localhost:%d, authkey=%s..' % (os.getpid(), port, repr(authkey)))
conn = multiprocessing.connection.Client(('localhost', int(port)), authkey=authkey)
if debug:
print('[%d] connected; starting remote proxy.' % os.getpid())
global HANDLER
#ppid = 0 if not hasattr(os, 'getppid') else os.getppid()
HANDLER = RemoteEventHandler(conn, name, ppid, debug=debug)
@ -380,7 +389,12 @@ class QtProcess(Process):
self.timer.stop()
def startQtEventLoop(name, port, authkey, ppid, debug=False):
if debug:
import os
print('[%d] connecting to server at port localhost:%d, authkey=%s..' % (os.getpid(), port, repr(authkey)))
conn = multiprocessing.connection.Client(('localhost', int(port)), authkey=authkey)
if debug:
print('[%d] connected; starting remote proxy.' % os.getpid())
from pyqtgraph.Qt import QtGui, QtCore
#from PyQt4 import QtGui, QtCore
app = QtGui.QApplication.instance()

View File

@ -97,7 +97,6 @@ class RemoteEventHandler(object):
after no more events are immediately available. (non-blocking)
Returns the number of events processed.
"""
self.debugMsg('processRequests:')
if self.exited:
self.debugMsg(' processRequests: exited already; raise ClosedError.')
raise ClosedError()
@ -108,7 +107,7 @@ class RemoteEventHandler(object):
self.handleRequest()
numProcessed += 1
except ClosedError:
self.debugMsg(' processRequests: got ClosedError from handleRequest; setting exited=True.')
self.debugMsg('processRequests: got ClosedError from handleRequest; setting exited=True.')
self.exited = True
raise
#except IOError as err: ## let handleRequest take care of this.
@ -121,7 +120,8 @@ class RemoteEventHandler(object):
print("Error in process %s" % self.name)
sys.excepthook(*sys.exc_info())
self.debugMsg(' processRequests: finished %d requests' % numProcessed)
if numProcessed > 0:
self.debugMsg('processRequests: finished %d requests' % numProcessed)
return numProcessed
def handleRequest(self):

View File

@ -188,11 +188,16 @@ 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))
# different versions of pyqt have different requirements here..
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)
try:
self.img = QtGui.QImage(memoryview(buffer(self.shm)), self.width(), self.height(), QtGui.QImage.Format_ARGB32)
except TypeError:
# Works on PyQt 4.9.6
self.img = QtGui.QImage(address, self.width(), self.height(), QtGui.QImage.Format_ARGB32)
self.img.fill(0xffffffff)
p = QtGui.QPainter(self.img)
self.render(p, self.viewRect(), self.rect())
@ -236,6 +241,3 @@ class Renderer(GraphicsView):
ev = QtCore.QEvent(QtCore.QEvent.Type(typ))
return GraphicsView.leaveEvent(self, ev)