Skip to content

Writing Gui Clients

Hlab edited this page Apr 3, 2014 · 36 revisions

Introduction

This page describes how to write GUI clients using the PyQt4 Python library. We assume some familiarity with PyQt, please see this tutorial for an excellent introduction for writing PyQt programs. We explain how to create a LabRAD client that encompasses a graphical user interface containing, buttons, spinboxes, dropdown menus, and any other PyQt widgets. The created clients are similar to scripts in that they interface with a server and are able to execute server settings in response to user action i.e pressing a button. In addition, GUI clients are able subscribe to signals from the server and act in response to these signals being emitted. For these reasons, GUI clients are referred to as asynchronous clients.

First Client

LabRAD is built on top of the twisted Python library. Within twisted, the timing of all events is controlled by an event loop called a reactor. Similarly to twisted, PyQt has its own reactor to control the timing graphical events. For the two libraries to work together, the two event loops must be combined. This is done with a freely available qt4reactor as follows (the file is available in the tutorial folder):

from twisted.internet.defer import inlineCallbacks
from PyQt4 import QtGui

class sampleWidget(QtGui.QWidget):
    def __init__(self, reactor, parent=None):
        super(sampleWidget, self).__init__(parent)
        self.reactor = reactor
        self.connect()

    @inlineCallbacks
    def connect(self):
        from labrad.wrappers import connectAsync
        self.cxn = yield connectAsync()

    def closeEvent(self, x):
        self.reactor.stop()   

if __name__=="__main__":
    a = QtGui.QApplication( [] )
    import qt4reactor
    qt4reactor.install()
    from twisted.internet import reactor
    widget = sampleWidget(reactor)
    widget.show()
    reactor.run()

As seen in the example, we first create a QApplication instance and then import and install the qt4reactor, which integrates twisted into the Qt mainloop. Only after this is done, we can import the twisted reactor, create the widget, show it and then start the reactor.

The created sampleWidget inherits from the QWidget class. When constructing sampleWidget, we pass the twisted reactor. This way the widget will know to stop the reactor when it's closed and closeEvent method is executed. The example also shows the connect method, which creates an asynchronous connection to the manager. The syntax is the same as while writing servers: use yield keyword to wait for deferred methods to return a value, and @inlineCallbacks decorators when yielding.

Reactor already installed error

It is important to run qt4reactor.install() before ever importing the twisted reactor. Otherwise, we will get an error reactor already installed. Note that the twisted reactor is imported whenever we import any other LabRAD classes i.e from labrad.units import WithUnit. To avoid the error, all of such imports must be done after qt4reactor.install().

Advanced

The twisted reactor is installed inside __init__.py within the LabRAD directory. Probably there is no reason to need for it to be automatically imported when accessing WithUnit.

Connecting Layout

Signaling

guidelines