class Client(QDialog): def __init__(self, parent=None): super(Client, self).__init__(parent) self.blockSize = 0 self.currentFortune = None hostLabel = QLabel("&Server name:") self.hostLineEdit = QLineEdit("fortune") hostLabel.setBuddy(self.hostLineEdit) self.statusLabel = QLabel( "This examples requires that you run the Fortune Server " "example as well.") self.statusLabel.setWordWrap(True) self.getFortuneButton = QPushButton("Get Fortune") self.getFortuneButton.setDefault(True) quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self.socket = QLocalSocket() self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.socket.readyRead.connect(self.readFortune) self.socket.error.connect(self.displayError) mainLayout = QGridLayout() mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostLineEdit, 0, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Fortune Client") self.hostLineEdit.setFocus() def requestNewFortune(self): self.getFortuneButton.setEnabled(False) self.blockSize = 0 self.socket.abort() self.socket.connectToServer(self.hostLineEdit.text()) def readFortune(self): ins = QDataStream(self.socket) ins.setVersion(QDataStream.Qt_4_0) if self.blockSize == 0: if self.socket.bytesAvailable() < 2: return self.blockSize = ins.readUInt16() if ins.atEnd(): return nextFortune = ins.readQString() if nextFortune == self.currentFortune: QTimer.singleShot(0, self.requestNewFortune) return self.currentFortune = nextFortune self.statusLabel.setText(self.currentFortune) self.getFortuneButton.setEnabled(True) def displayError(self, socketError): errors = { QLocalSocket.ServerNotFoundError: "The host was not found. Please check the host name and port " "settings.", QLocalSocket.ConnectionRefusedError: "The connection was refused by the peer. Make sure the " "fortune server is running, and check that the host name and " "port settings are correct.", QLocalSocket.PeerClosedError: None, } msg = errors.get( socketError, "The following error occurred: %s." % self.socket.errorString()) if msg is not None: QMessageBox.information(self, "Fortune Client", msg) self.getFortuneButton.setEnabled(True) def enableGetFortuneButton(self): self.getFortuneButton.setEnabled(self.hostLineEdit.text() != "")
class Client(QDialog): def __init__(self, parent=None): super(Client, self).__init__(parent) self.blockSize = 0 self.currentFortune = None hostLabel = QLabel("&Server name:") self.hostLineEdit = QLineEdit("fortune") hostLabel.setBuddy(self.hostLineEdit) self.statusLabel = QLabel("This examples requires that you run the Fortune Server " "example as well.") self.statusLabel.setWordWrap(True) self.getFortuneButton = QPushButton("Get Fortune") self.getFortuneButton.setDefault(True) quitButton = QPushButton("Quit") buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self.socket = QLocalSocket() self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.socket.readyRead.connect(self.readFortune) self.socket.error.connect(self.displayError) mainLayout = QGridLayout() mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostLineEdit, 0, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setLayout(mainLayout) self.setWindowTitle("Fortune Client") self.hostLineEdit.setFocus() def requestNewFortune(self): self.getFortuneButton.setEnabled(False) self.blockSize = 0 self.socket.abort() self.socket.connectToServer(self.hostLineEdit.text()) def readFortune(self): ins = QDataStream(self.socket) ins.setVersion(QDataStream.Qt_4_0) if self.blockSize == 0: if self.socket.bytesAvailable() < 2: return self.blockSize = ins.readUInt16() if ins.atEnd(): return nextFortune = ins.readQString() if nextFortune == self.currentFortune: QTimer.singleShot(0, self.requestNewFortune) return self.currentFortune = nextFortune self.statusLabel.setText(self.currentFortune) self.getFortuneButton.setEnabled(True) def displayError(self, socketError): errors = { QLocalSocket.ServerNotFoundError: "The host was not found. Please check the host name and port " "settings.", QLocalSocket.ConnectionRefusedError: "The connection was refused by the peer. Make sure the " "fortune server is running, and check that the host name and " "port settings are correct.", QLocalSocket.PeerClosedError: None, } msg = errors.get(socketError, "The following error occurred: %s." % self.socket.errorString()) if msg is not None: QMessageBox.information(self, "Fortune Client", msg) self.getFortuneButton.setEnabled(True) def enableGetFortuneButton(self): self.getFortuneButton.setEnabled(self.hostLineEdit.text() != "")
class LivePlotClient(object): def __init__(self, timeout=2000, size=2**28): self.app = QCoreApplication.instance() if self.app is None: self.app = QCoreApplication([]) self.sock = QLocalSocket() self.sock.connectToServer("LivePlot") if not self.sock.waitForConnected(): raise EnvironmentError("Couldn't find LivePlotter instance") self.sock.disconnected.connect(self.disconnect_received) key = str(uuid.uuid4()) self.shared_mem = QSharedMemory(key) if not self.shared_mem.create(size): raise Exception("Couldn't create shared memory %s" % self.shared_mem.errorString()) logging.debug('Memory created with key %s and size %s' % (key, self.shared_mem.size())) self.sock.write(key.encode()) self.sock.waitForBytesWritten() self.is_connected = True self.timeout = timeout atexit.register(self.close) def close(self): self.shared_mem.detach() def send_to_plotter(self, meta, arr=None): if not self.is_connected: return if meta["name"] is None: meta["name"] = "*" if arr is not None: arrbytes = bytearray(arr) arrsize = len(arrbytes) if arrsize > self.shared_mem.size(): raise ValueError("Array too big %s > %s" % (arrsize, self.shared_mem.size())) meta['arrsize'] = arrsize meta['dtype'] = str(arr.dtype) meta['shape'] = arr.shape else: meta['arrsize'] = 0 meta_bytes = json.dumps(meta).ljust(300) if len(meta_bytes) > 300: raise ValueError("meta object is too large (> 300 char)") if arr is None: self.sock.write(meta_bytes.encode()) else: if not self.sock.bytesAvailable(): self.sock.waitForReadyRead() self.sock.read(2) self.shared_mem.lock() self.sock.write(meta_bytes.encode()) region = self.shared_mem.data() region[:arrsize] = arrbytes self.shared_mem.unlock() def plot_y(self, name, arr, extent=None, start_step=(0, 1), label=''): arr = np.array(arr) if extent is not None and start_step is not None: raise ValueError( 'extent and start_step provide the same info and are thus mutually exclusive' ) if extent is not None: x0, x1 = extent nx = len(arr) start_step = x0, float(x1 - x0) / nx meta = { 'name': name, 'operation': 'plot_y', 'start_step': start_step, 'rank': 1, 'label': label, } self.send_to_plotter(meta, arr.astype('float64')) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def plot_z(self, name, arr, extent=None, start_step=None, xname='X axis',\ xscale='arb. u.', yname='Y axis', yscale='arb. u.', zname='Y axis', zscale='arb. u.'): ''' extent is ((initial x, final x), (initial y, final y)) start_step is ((initial x, delta x), (initial_y, final_y)) ''' arr = np.array(arr) if extent is not None and start_step is not None: raise ValueError( 'extent and start_step provide the same info and are thus mutually exclusive' ) if extent is not None: (x0, x1), (y0, y1) = extent nx, ny = arr.shape start_step = (x0, float(x1 - x0) / nx), (y0, float(y1 - y0) / ny) meta = { 'name': name, 'operation': 'plot_z', 'rank': 2, 'start_step': start_step, 'X': xscale, 'Y': yscale, 'Z': zscale, 'Xname': xname, 'Yname': yname, 'Zname': zname, } self.send_to_plotter(meta, arr.astype('float64')) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def plot_xy(self, name, xs, ys, label='', xname='X axis', xscale='arb. u.',\ yname='Y axis', yscale='arb. u.', scatter='False', timeaxis='False'): arr = np.array([xs, ys]) meta = { 'name': name, 'operation': 'plot_xy', 'rank': 1, 'label': label, 'X': xscale, 'Y': yscale, 'Xname': xname, 'Yname': yname, 'Scatter': scatter, 'TimeAxis': timeaxis } self.send_to_plotter(meta, np.array([xs, ys]).astype('float64')) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def append_y(self, name, point, start_step=(0, 1), label='', xname='X axis',\ xscale='arb. u.', yname='Y axis', yscale='arb. u.',scatter='False', timeaxis='False'): self.send_to_plotter({ 'name': name, 'operation': 'append_y', 'value': point, 'start_step': start_step, 'rank': 1, 'label': label, 'X': xscale, 'Y': yscale, 'Xname': xname, 'Yname': yname, 'Scatter': scatter, 'TimeAxis': timeaxis }) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def append_xy(self, name, x, y, label=''): self.send_to_plotter({ 'name': name, 'operation': 'append_xy', 'value': (x, y), 'rank': 1, 'label': label, }) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def append_z(self, name, arr, start_step=None, xname='X axis',\ xscale='arb. u.', yname='Y axis', yscale='arb. u.', zname='Y axis', zscale='arb. u.'): arr = np.array(arr) meta = { 'name': name, 'operation': 'append_z', 'rank': 2, 'start_step': start_step, 'X': xscale, 'Y': yscale, 'Z': zscale, 'Xname': xname, 'Yname': yname, 'Zname': zname, } self.send_to_plotter(meta, arr.astype('float64')) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def label(self, name, text): self.send_to_plotter({ 'name': name, 'operation': 'label', 'value': text }) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def clear(self, name=None): self.send_to_plotter({'name': name, 'operation': 'clear'}) def hide(self, name=None): self.send_to_plotter({'name': name, 'operation': 'close'}) def remove(self, name=None): self.send_to_plotter({'name': name, 'operation': 'remove'}) self.send_to_plotter({ 'name': 'none', 'operation': 'none' }, np.array([0.])) def disconnect_received(self): self.is_connected = False warnings.warn( 'Disconnected from LivePlotter server, plotting has been disabled')
class Client(QDialog): def __init__(self, parent: QWidget = None): super().__init__(parent) self._in = QDataStream() self.blockSize = 0 self.currentFortune = "" self.hostLineEdit = QLineEdit("fortune") self.getFortuneButton = QPushButton(self.tr("Get Fortune")) self.statusLabel = QLabel( self. tr("This examples requires that you run the Local Fortune Server example as well." )) self.socket = QLocalSocket(self) self.setWindowFlags(self.windowFlags() & ~Qt.WindowContextHelpButtonHint) hostLabel = QLabel(self.tr("&Server name:")) hostLabel.setBuddy(self.hostLineEdit) self.statusLabel.setWordWrap(True) self.getFortuneButton.setDefault(True) quitButton = QPushButton(self.tr("Quit")) buttonBox = QDialogButtonBox() buttonBox.addButton(self.getFortuneButton, QDialogButtonBox.ActionRole) buttonBox.addButton(quitButton, QDialogButtonBox.RejectRole) self._in.setDevice(self.socket) self._in.setVersion(QDataStream.Qt_5_10) self.hostLineEdit.textChanged.connect(self.enableGetFortuneButton) self.getFortuneButton.clicked.connect(self.requestNewFortune) quitButton.clicked.connect(self.close) self.socket.readyRead.connect(self.readFortune) self.socket.errorOccurred.connect(self.displayError) mainLayout = QGridLayout(self) mainLayout.addWidget(hostLabel, 0, 0) mainLayout.addWidget(self.hostLineEdit, 0, 1) mainLayout.addWidget(self.statusLabel, 2, 0, 1, 2) mainLayout.addWidget(buttonBox, 3, 0, 1, 2) self.setWindowTitle(QGuiApplication.applicationDisplayName()) self.hostLineEdit.setFocus() @pyqtSlot() def requestNewFortune(self): self.getFortuneButton.setEnabled(False) self.blockSize = 0 self.socket.abort() self.socket.connectToServer(self.hostLineEdit.text()) @pyqtSlot() def readFortune(self): if self.blockSize == 0: # Relies on the fact that QDataStream serializes a quint32 into # sizeof(quint32) bytes if self.socket.bytesAvailable() < 4: # (int)sizeof(quint32)) return self.blockSize = self._in.readUInt32() if self.socket.bytesAvailable() < self.blockSize or self._in.atEnd(): return nextFortune = "" nextFortune = self._in.readQString() if nextFortune == self.currentFortune: QTimer.singleShot(0, self.requestNewFortune) return currentFortune = nextFortune self.statusLabel.setText(currentFortune) self.getFortuneButton.setEnabled(True) @pyqtSlot(QLocalSocket.LocalSocketError) def displayError(self, socketError): if socketError == QLocalSocket.ServerNotFoundError: QMessageBox.information( self, self.tr("Local Fortune Client"), self.tr("The host was not found. Please make sure " "that the server is running and that the " "server name is correct."), ) elif socketError == QLocalSocket.ConnectionRefusedError: QMessageBox.information( self, self.tr("Local Fortune Client"), self.tr("The connection was refused by the peer. " "Make sure the fortune server is running, " "and check that the server name is correct."), ) elif socketError == QLocalSocket.PeerClosedError: return else: QMessageBox.information( self, self.tr("Local Fortune Client"), self.tr("The following error occurred: %s." % (self.socket.errorString())), ) self.getFortuneButton.setEnabled(True) @pyqtSlot() def enableGetFortuneButton(self): self.getFortuneButton.setEnabled(bool(self.hostLineEdit.ext()))