labrad / pylabrad

python interface for labrad
50 stars 31 forks source link

Asynchronous Remote Labrad Connections #367

Open mserlin opened 5 years ago

mserlin commented 5 years ago

I'm am developing a GUI using pyqt4 and labrad to perform SPM experiments. The GUI has grown substantially over the past couple years and recently has started crashing very suddenly, without throwing error messages of any kind.

When an asynchronous local labrad connection is created, everything works as intended. However, when a remote asynchronous connection is created, the software no longer closes cleanly. Disconnecting the remote labrad connection prior to closing the software does not fix it. I'm suspicious that this is an indication of the remote connection not integrating properly with twisted's reactor somehow, and might be responsible for the sudden software crashes.

I am using pylabrad version 0.97.2, twisted version 17.5.0, qt4reactor 1.6, and pyqt4. Below I attached a very simple GUI that demonstrates the problem on my computer.

Does anyone have any ideas what could be causing this? Is there a different, more proper way to close a labrad connection? Am I doing anything obviously incorrectly in terms of starting the asynchronous connections?

Any help or insight would be appreciated. Thanks!

import sys
from PyQt4 import Qt, QtGui, QtCore
from twisted.internet.defer import inlineCallbacks, Deferred

class MainWindow(QtGui.QMainWindow):
    def __init__(self, reactor, parent=None):
        super(MainWindow, self).__init__(parent)
        self.reactor = reactor
        self.resize(250,250)
        self.move(300,300)

        btn = QtGui.QPushButton('Connect Local', self)
        btn.resize(QtCore.QSize(150,23))
        btn.move(50, 50)

        btn2 = QtGui.QPushButton('Connect Remote', self)
        btn2.resize(QtCore.QSize(150,23))
        btn2.move(50, 100)

        btn3 = QtGui.QPushButton('Disconnect Remote', self)
        btn3.resize(QtCore.QSize(150,23))
        btn3.move(50, 150)

        btn.clicked.connect(lambda: self.connectLocalLabrad())
        btn2.clicked.connect(lambda: self.connectRemoteLabrad())
        btn3.clicked.connect(lambda: self.disconnectRemoteLabrad())

    @inlineCallbacks
    def connectLocalLabrad(self):
        from labrad.wrappers import connectAsync
        try:
            #Connects to the manager on the local computer. 
            self.cxn = yield connectAsync(host = '127.0.0.1', password = 'pass')

            self.dv = self.cxn.data_vault

            print 'Connected locally'
        except:
            print 'Local connection failed'

    @inlineCallbacks
    def connectRemoteLabrad(self):
        from labrad.wrappers import connectAsync
        try:
            self.cxnr = yield connectAsync(host = '4KMonitor', password = 'pass')
            print 'Connected remotely'
        except:
            print 'Remote connection failed'

    @inlineCallbacks
    def disconnectRemoteLabrad(self):
        from labrad.wrappers import connectAsync
        try:
            yield self.cxnr.disconnect()
            print 'Disconnected remotely'
        except:
            print 'Remote disconnection failed'

if __name__=="__main__":
    import qt4reactor
    app = QtGui.QApplication(sys.argv)
    qt4reactor.install()
    from twisted.internet import reactor
    window = MainWindow(reactor)
    window.show()
    reactor.runReturn()
    sys.exit(app.exec_())