Remote plotting in a GUI

1,401 views
Skip to first unread message

Ruben de Groote

unread,
Mar 11, 2014, 4:55:02 PM3/11/14
to pyqt...@googlegroups.com

Hi everyone,

I want to take advantage of pyqtgraphs mutliprocessing to remotely update a plot in a GUI. In my application, such two plots are added to separate docks.

Toying around with the example found here, I came up with the code shown below as a start.
In this example. the addWidget throws an error:
TypeError: arguments did not match any overloaded call:
  QGridLayout.addWidget(QWidget): argument 1 has unexpected type 'ObjectProxy'

Clearly, I can only add QWidgets to a layout. Suggestions?

P.S. I tried using RemoteGraphicsView as well, but then I cannot seem to create more than one RemoteGraphicsView - the GUI never shows, and the program crashes. I think I need more than one, since I want two plots, each in a separate dock.

_________

import pyqtgraph as pg
import PyQt4.QtGui as QtGui
import PyQt4.QtCore as QtCore
import pyqtgraph.multiprocess as mp



pg.mkQApp()

window = QtGui.QMainWindow()
centr = QtGui.QWidget()
window.setCentralWidget(centr)
grid = QtGui.QGridLayout()
centr.setLayout(grid)
window.show()


proc = mp.QtProcess()
rpg = proc._import('pyqtgraph')

gwin = rpg.GraphicsWindow()
plotItem = gwin.addPlot()
curve = plotItem.plot(pen='y')

grid.addWidget(gwin)


data = proc.transfer([])

data.extend([1,5,2,4,3], _callSync='off')
curve.setData(y=data, _callSync='off')
if __name__ == '__main__':
    import sys
    if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
        QtGui.QApplication.instance().exec_()

Luke Campagnola

unread,
Mar 11, 2014, 8:36:03 PM3/11/14
to pyqt...@googlegroups.com
On Tue, Mar 11, 2014 at 4:55 PM, Ruben de Groote <rdeg...@gmail.com> wrote:
Toying around with the example found here, I came up with the code shown below as a start.
In this example. the addWidget throws an error:
TypeError: arguments did not match any overloaded call:
  QGridLayout.addWidget(QWidget): argument 1 has unexpected type 'ObjectProxy'

Clearly, I can only add QWidgets to a layout. Suggestions?

Correct--if the widget is created in the remote process, then it cannot be attached to the parent process' GUI. Your only option there is to display the remote widget in a separate window. 

(Aside: this IS technically possible, but I have not tried it. see QX11EmbedWidget for linux. I think there are other solutions for windows and OSX..)

P.S. I tried using RemoteGraphicsView as well, but then I cannot seem to create more than one RemoteGraphicsView - the GUI never shows, and the program crashes. I think I need more than one, since I want two plots, each in a separate dock.

This should be possible. Can you write a short script that demonstrates the problem, and also tell me your OS and pyqtgraph version?
The following example works for me:

import pyqtgraph as pg
from pyqtgraph.widgets.RemoteGraphicsView import RemoteGraphicsView
app = pg.mkQApp()

win = pg.LayoutWidget()
rv1 = RemoteGraphicsView()
rv2 = RemoteGraphicsView()
win.addWidget(rv1)
win.addWidget(rv2)
win.show()

p1 = rv1.pg.PlotItem()
rv1.setCentralItem(p1)
p1.plot([1,4,2,3,6,2,3,4,2,3], pen='g')

p2 = rv2.pg.PlotItem()
rv2.setCentralItem(p2)
p2.plot([1,4,2,3,6,2,3,4,2,3], pen='r')


Ruben de Groote

unread,
Mar 12, 2014, 5:37:46 AM3/12/14
to pyqt...@googlegroups.com
Hi Luke,

I tried things like your example before, but they don't work for some reason.  I see three python processes being created using the task manager, but the window does not appear. No errors are thrown either.
One RemoteGraphicsView works just fine.

I'm on windows 7, using pyqtgraph 0.9.8 (using the latest installer found on the website).

Luke Campagnola

unread,
Mar 12, 2014, 8:04:07 AM3/12/14
to pyqt...@googlegroups.com
On Wed, Mar 12, 2014 at 5:37 AM, Ruben de Groote <rdeg...@gmail.com> wrote:
I tried things like your example before, but they don't work for some reason.  I see three python processes being created using the task manager, but the window does not appear. No errors are thrown either.
One RemoteGraphicsView works just fine.

I'm on windows 7, using pyqtgraph 0.9.8 (using the latest installer found on the website).

Ok, I'll give it a try on Windows.

Ruben de Groote

unread,
Mar 12, 2014, 10:41:16 AM3/12/14
to pyqt...@googlegroups.com
Thanks Luke :)!

Luke Campagnola

unread,
Mar 14, 2014, 7:10:49 PM3/14/14
to pyqt...@googlegroups.com
On Wed, Mar 12, 2014 at 5:37 AM, Ruben de Groote <rdeg...@gmail.com> wrote:
I tried things like your example before, but they don't work for some reason.  I see three python processes being created using the task manager, but the window does not appear. No errors are thrown either.

The latest develop branch on github fixes a deadlock I ran into on Windows, but I am not sure it matches the problem you described. I would be interested to see whether this solves your problem..
 

Ruben de Groote

unread,
Mar 16, 2014, 7:23:40 AM3/16/14
to pyqt...@googlegroups.com

Hi Luke,

I'll have a look later today. 

Ruben

Ruben de Groote

unread,
Mar 16, 2014, 2:30:40 PM3/16/14
to pyqt...@googlegroups.com
Hi Luke,


It works now! You're a wizard.

I'll work this into my application as soon as I can :).




Thanks!

Ruben

Ruben de Groote

unread,
Mar 17, 2014, 11:15:28 AM3/17/14
to pyqt...@googlegroups.com

I've succesfully implemented RemoteGraphicsViews into my GUI, and it works like a charm.

Follow-up question. In my original code (with non-remote plotItems), I had subclassed ViewBox to change some of the mouse interaction - when the user double-clicked on the graph, I emitted a QtSignal with the position of the click.
Could I implement such a feature using the RemoteGraphicsView? I tried to pass an instance of my subclass when creating the plotItem (e.g. view.pg.PlotItem(viewBox = myViewBox()), but that threw the error shown below.

Suggestions?

===== 2014.03.17 16:03:49 =====
Traceback (most recent call last):
 (snip)
  File "MyPath\myFile.py", line 41, in __init__
    self.graph = self.view.pg.PlotItem(viewBox = MyViewBox())
  File "C:\Python27\lib\site-packages\pyqtgraph\multiprocess\remoteproxy.py", line 864, in __call__
    return self._handler.callObj(obj=self, args=args, kwds=kwds, **opts)
  File "C:\Python27\lib\site-packages\pyqtgraph\multiprocess\remoteproxy.py", line 520, in callObj
    return self.send(request='callObj', opts=dict(obj=obj, args=args, kwds=kwds), byteData=byteMsgs, **opts)
  File "C:\Python27\lib\site-packages\pyqtgraph\multiprocess\remoteproxy.py", line 403, in send
    optStr = pickle.dumps(opts)
  File "C:\Python27\lib\copy_reg.py", line 71, in _reduce_ex
    state = base(self)
TypeError: the sip.wrapper type cannot be instantiated or sub-classed

Luke Campagnola

unread,
Mar 17, 2014, 12:00:50 PM3/17/14
to pyqt...@googlegroups.com
On Mon, Mar 17, 2014 at 11:15 AM, Ruben de Groote <rdeg...@gmail.com> wrote:

I've succesfully implemented RemoteGraphicsViews into my GUI, and it works like a charm.

Follow-up question. In my original code (with non-remote plotItems), I had subclassed ViewBox to change some of the mouse interaction - when the user double-clicked on the graph, I emitted a QtSignal with the position of the click.
Could I implement such a feature using the RemoteGraphicsView? I tried to pass an instance of my subclass when creating the plotItem (e.g. view.pg.PlotItem(viewBox = myViewBox()), but that threw the error shown below.

Objects can only be passed from one process to another if they are serializable using pickle. Generally that means you are limited to sending basic python types and numpy arrays. Everything else can only be accessed by proxy, so you just need to create your ViewBox instance on the remote process. Everything else should look about the same, including the signal connections.

 

Ruben de Groote

unread,
Mar 17, 2014, 3:12:06 PM3/17/14
to pyqt...@googlegroups.com
Ok, that makes a lot of sense. Thanks Luke!
Reply all
Reply to author
Forward
0 new messages