Connecting two (or more) widgets to the same feat

In many cases you want to have multiple widgets (e.g. different kind) connected to the same Feat. When the two widgets are together you could create a custom widget, but with Lantz it is not necessary. Consider the following UI:

Two widgets to the same Feat

You can set the frequency using the slider or the double spin box. The slider is named frequency__slider and the spin is named frequency.

For educational purposes, we show you three ways to do this. You will certainly use only the last and shortest way but showing you how it is done allows you to understand what is going on.

The long way

You can connect each relevant driver Feat to the corresponding widget:

import sys

# Import Qt related from lantz so it worsk with PyQt4 or PySide ...
from lantz.utils.qt import QtGui

# From lantz we import the driver ...
from lantz.drivers.examples.fungen import LantzSignalGeneratorTCP

# and a function named connect_feat that does the work.
from lantz.ui.widgets import connect_feat

app = QtGui.QApplication(sys.argv)

# We load the UI from the QtDesigner file. You can also use pyuic4 to generate a class.
main = QtGui.loadUi('connect_test.ui')

# We get a reference to each of the widgets.
slider = main.findChild((QtGui.QWidget, ), 'frequency__slider')
spin = main.findChild((QtGui.QWidget, ), 'frequency')

with LantzSignalGeneratorTCP('localhost', 5678) as inst:

    # We connect each widget to each feature
    # The syntax arguments are widget, target (driver), Feat name
    connect_feat(slider, inst, 'frequency')
    connect_feat(spin, inst, 'frequency')
    main.show()
    exit(app.exec_())

and that is all. Try it out and see how when you change one control the other one is updated.

The short way

If you have named the widgets according to the Feat and you have use a suffix in at least one of them, you can use connect_driver:

import sys

# Import Qt related from lantz so it worsk with PyQt4 or PySide ...
from lantz.utils.qt import QtGui

# From lantz we import the driver ...
from lantz.drivers.examples.fungen import LantzSignalGeneratorTCP

# and a function named connect_feat that does the work.
from lantz.ui.widgets import connect_feat

app = QtGui.QApplication(sys.argv)

# We load the UI from the QtDesigner file. You can also use pyuic4 to generate a class.
main = QtGui.loadUi('connect_test.ui')

with LantzSignalGeneratorTCP('localhost', 5678) as inst:

    # We connect the parent widget (main) to the instrument.
    connect_driver(main, inst)
    main.show()
    exit(app.exec_())

Notice that now we do not need a reference to the widgets (only to the parent widget, here named main). And we call connect_driver (instead of connect_feat) without specifying the feat name. Under the hood, connect_driver is iterating over all widgets and checking if the driver contains a Feat with the widget name stripped from the suffix. If it does, it executes connect_feat.

In this example, we have use the double underscore __ to separate the suffix. This is a good choice and also the default as can be used in Qt and Python variable names. If you want have used another separator, you can specify it by passing the sep keyword argument:

connect_driver(main, inst, sep='_o_')

There is no limit in the number of widgets that you can connect to the same feat.

The shortest way

As this is a commont pattern, we have a useful function for that:

import sys

# Import Qt related from lantz so it worsk with PyQt4 or PySide ...
from lantz.ui.app import start_gui

with LantzSignalGeneratorTCP('localhost', 5678) as inst:
    start_gui('connect_test.ui', inst, sys.argv)