Interactive and real time updating of guidata widgets

214 views
Skip to first unread message

David

unread,
Feb 10, 2011, 11:32:02 PM2/10/11
to guidata/guiqwt
Hello Pierre,

I am currently using PyQt and pyvisa for some of my scripts to control
instruments in the lab (basically as an alternative to labview). The
one problem I found is that I spend a lot of time thinking about Qt4
related things (signals, slots, widgets etc), rather than my actual
data.

It seems to me that guidata would be the perfect solution for me,
since it abstracts away a lot of the underlying Qt framework. I had a
quick play around with it, and I am quite impressed by what you have
done, however it seems that it may be too "static" for my needs. What
I mean is that you have to click "Apply" after editing every dataset,
whereas I would like the changes to take effect as soon as I update
the widget (or after I press enter or move to another widget). Also,
a dataset may be displayed for user editing, but might also be updated
in response to an external signal from some instrument.

So my question is whether it is feasible for guidata to be used in
such real-time situations, if you have any plans to move in this
direction, or any obstacles I might come across if I tried to
implement such changes myself.

cheers
David

Pierre Raybaut

unread,
Apr 6, 2011, 6:04:48 AM4/6/11
to guidata/guiqwt
Hi David,

guidata v1.3.0 includes more interactivity.
It's not very well documented for now, but you may try setting the
options "callback" and "value_callback" of the "display" properties of
items. Only items which are represented by a QLineEdit widget support
this feature (e.g. FloatItem, StringItem, IntItem, FileOpenItem,
etc.).

A simple example (not tested though):

def func1(instance, item, value):
# instance: instance of the Example dataset
# item: instance of the FloatItem
print "callback, x:", value

def func2(value):
print "value_callback, x:", value

class Example(DataSet):
item = FloatItem("x").set_prop("display", callback=func1,
value_callback=func2)

-Pierre

stefan

unread,
Apr 8, 2011, 12:56:49 AM4/8/11
to guidata/guiqwt
When I try this, it works and I do get calls to func1 and func2 when
the value changes.

However, it seems to me a bit awkward although my lack of
understanding of python could be a problem:
As I understand this, func1 is a function outside of class Example and
also not at all connected to the DataSetEditGroupBox that makes use of
it. How would one communicate with the ImageDialog object that this
parameter set is a part of? I'm trying to update the image display as
a function of an integer input (similar to simple_dialog.py) but I
would rather just input the number or, even better, just use a
slider...

Thanks, Stefan

Pierre Raybaut

unread,
Apr 10, 2011, 1:27:29 PM4/10/11
to guidata/guiqwt
On 8 avr, 06:56, stefan <stefan.reinsb...@gmail.com> wrote:
> When I try this, it works and I do get calls to func1 and func2 when
> the value changes.
>
> However, it seems to me a bit awkward although my lack of
> understanding of python could be a problem:
> As I understand this, func1 is a function outside of class Example and
> also not at all connected to the DataSetEditGroupBox that makes use of
> it. How would one communicate with the ImageDialog object that this
> parameter set is a part of? I'm trying to update the image display as
> a function of an integer input (similar to simple_dialog.py) but I
> would rather just input the number or, even better, just use a
> slider...

Actually you have a lot of options to implement this link between the
DataSet instance and the ImageDialog instance.
Let's say you have a class named MainWindow deriving from QMainWindow
and containing an ImageDialog instance and other widgets, like this
for example:

class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
self.imagedialog = None
self.widget1 = None
self.widget2 = None
self.setup_layout()

def setup_layout(self):
# setup your mainwindow's layout: constructing widgets,
setting the central widget, ...
pass

Examples:

(1) define a custom DataSet class with an attribute keeping a
reference to MainWindow object (to do this properly, you have to
override the DataSet constructor and implement your own, see below)

class MyDataSet(DataSet):
def __init__(self, title=None, comment=None, icon=''):
super(MyDataSet, self).__init__(title, comment, icon)
self.mainwindow = None

def set_mainwindow(self, mainwindow):
self.mainwindow = mainwindow

# then define your data items as usual:
x = FloatItem("foobar")

First create the DataSet, and then bind it to your main window
instance:
param = MyDataSet()
param.set_mainwindow(mainwindow) # or param.set_mainwindow(self) if
you are in one of the main window methods

Then your callback will be able to do things with your mainwindow
object: you may for example implement another method in your MyDataSet
class to specify actions to do with the mainwindow object.

(2) define a standard DataSet class but within a method of MainWindow:

class MainWindow(QMainWindow):
...
def some_method(self):
class MyDataSet(DataSet):
x = FloatItem("foobar")
# then, your callback functions may be methods of the
mainwindow objects, so they will have access to this object

HTH,
Pierre
Reply all
Reply to author
Forward
0 new messages