def _has_legacy_server(name): """Check if there is a legacy server. Args: name: The name to try to connect to. Return: True if there is a server with the given name, False otherwise. """ socket = QLocalSocket() log.ipc.debug("Trying to connect to {}".format(name)) socket.connectToServer(name) err = socket.error() if err != QLocalSocket.UnknownSocketError: log.ipc.debug("Socket error: {} ({})".format( socket.errorString(), err)) os_x_fail = (sys.platform == 'darwin' and socket.errorString() == 'QLocalSocket::connectToServer: ' 'Unknown error 38') if err not in [QLocalSocket.ServerNotFoundError, QLocalSocket.ConnectionRefusedError] and not os_x_fail: return True socket.disconnectFromServer() if socket.state() != QLocalSocket.UnconnectedState: socket.waitForDisconnected(CONNECT_TIMEOUT) return False
def _has_legacy_server(name): """Check if there is a legacy server. Args: name: The name to try to connect to. Return: True if there is a server with the given name, False otherwise. """ socket = QLocalSocket() log.ipc.debug("Trying to connect to {}".format(name)) socket.connectToServer(name) err = socket.error() if err != QLocalSocket.UnknownSocketError: log.ipc.debug("Socket error: {} ({})".format(socket.errorString(), err)) os_x_fail = ( sys.platform == "darwin" and socket.errorString() == "QLocalSocket::connectToServer: " "Unknown error 38" ) if err not in [QLocalSocket.ServerNotFoundError, QLocalSocket.ConnectionRefusedError] and not os_x_fail: return True socket.disconnectFromServer() if socket.state() != QLocalSocket.UnconnectedState: socket.waitForDisconnected(CONNECT_TIMEOUT) return False
def sendNotification(self, message): if self.isRunning(): socket = QLocalSocket(self) socket.connectToServer(self._key, QIODevice.WriteOnly) if not socket.waitForConnected(self._timeout): print(socket.errorString()) return False if not isinstance(message, bytes): message = message.encode('utf-8') socket.write(message) if not socket.waitForBytesWritten(self._timeout): print(socket.errorString()) return False socket.disconnectFromServer() return True return False
def hasPrevious(self, name, args): print("önceki socket kontrol ediliyor...") socket = QLocalSocket() socket.connectToServer(name, QLocalSocket.ReadWrite) if socket.waitForConnected(): print("Önceki instansa argümanlar gönderiliyor.") if len(args) > 1: socket.write(args[1]) else: pass socket.flush() return True print(socket.errorString()) return False
class Client: def __init__(self): self.socket = QLocalSocket() self.socket.setServerName(piony.G_SOCKET_NAME) self.socket.error.connect(self.displayError) self.socket.disconnected.connect(self.socket.deleteLater) def _log_(self, text, *args): logger.info(self.__class__.__qualname__ + ': ' + text, *args) def connect(self): self.socket.abort() self._log_("connection attempt") self.socket.connectToServer() def send(self, argv): data = QByteArray() out = QDataStream(data, QIODevice.WriteOnly) out.setVersion(QDataStream.Qt_5_0) out.writeQVariant(argv) self._log_("writes: %s", str(data)) self.socket.write(data) self.socket.flush() self.socket.disconnectFromServer() def displayError(self, err): msg = { QLocalSocket.ServerNotFoundError: "The host was not found. Check the host name and port.", QLocalSocket.ConnectionRefusedError: "The connection was refused by the peer. " "Check server is running, it's host and port.", QLocalSocket.PeerClosedError: "Peer was closed", # None, }.get(err, "Client error: {}.".format(self.socket.errorString())) self._log_(msg)
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 SingleApplicationClient(object): """ Class implementing the single application client base class. """ def __init__(self, name): """ Constructor @param name name of the local server to connect to (string) """ self.name = name self.connected = False def connect(self, timeout=10000): """ Public method to connect the single application client to its server. @param timeout connection timeout value in milliseconds @type int @return value indicating success or an error number. Value is one of: <table> <tr><td>0</td><td>No application is running</td></tr> <tr><td>1</td><td>Application is already running</td></tr> </table> """ self.sock = QLocalSocket() self.sock.connectToServer(self.name) if self.sock.waitForConnected(timeout): self.connected = True return 1 else: err = self.sock.error() if err == QLocalSocket.ServerNotFoundError: return 0 else: return -err def disconnect(self): """ Public method to disconnect from the Single Appliocation server. """ self.sock.disconnectFromServer() self.connected = False def processArgs(self, args): """ Public method to process the command line args passed to the UI. <b>Note</b>: This method must be overridden by subclasses. @param args command line args (list of strings) @exception RuntimeError raised to indicate that this method must be implemented by a subclass """ raise RuntimeError("'processArgs' must be overridden") def sendCommand(self, command, arguments): """ Public method to send the command to the application server. @param command command to be sent to the server @type str @param arguments list of command arguments @type list of str """ if self.connected: commandDict = { "command": command, "arguments": arguments, } self.sock.write(QByteArray( "{0}\n".format(json.dumps(commandDict)).encode() )) self.sock.flush() def errstr(self): """ Public method to return a meaningful error string for the last error. @return error string for the last error (string) """ return self.sock.errorString()
class SingleApplicationClient(object): """ Class implementing the single application client base class. """ def __init__(self, name): """ Constructor @param name name of the local server to connect to (string) """ self.name = name self.connected = False def connect(self): """ Public method to connect the single application client to its server. @return value indicating success or an error number. Value is one of: <table> <tr><td>0</td><td>No application is running</td></tr> <tr><td>1</td><td>Application is already running</td></tr> </table> """ self.sock = QLocalSocket() self.sock.connectToServer(self.name) if self.sock.waitForConnected(10000): self.connected = True return 1 else: err = self.sock.error() if err == QLocalSocket.ServerNotFoundError: return 0 else: return -err def disconnect(self): """ Public method to disconnect from the Single Appliocation server. """ self.sock.disconnectFromServer() self.connected = False def processArgs(self, args): """ Public method to process the command line args passed to the UI. <b>Note</b>: This method must be overridden by subclasses. @param args command line args (list of strings) @exception RuntimeError raised to indicate that this method must be implemented by a subclass """ raise RuntimeError("'processArgs' must be overridden") def sendCommand(self, cmd): """ Public method to send the command to the application server. @param cmd command to be sent (string) """ if self.connected: self.sock.write(cmd) self.sock.flush() def errstr(self): """ Public method to return a meaningful error string for the last error. @return error string for the last error (string) """ return self.sock.errorString()
class MainForm(QDialog): def __init__(self, parent = None): QDialog.__init__(self, parent) # If a Nemu instance is already running, this is as far as we go self.connectToRunning() self.holdOpen = False self.menuItems = [] self.allItems = [] self.favorites = [] self.currentItem = None self.menuFile = os.path.expanduser('~/.nemu/menu') self.favoritesFile = os.path.expanduser('~/.nemu/favorites') # NOTE: If you change this, also update migrate-settings self.settingsFile = os.path.expanduser('~/.nemu/settings') self.initSettings() self.server = QLocalServer() self.server.newConnection.connect(self.handleConnection) QLocalServer.removeServer('nemuSocket') self.server.listen('nemuSocket') self.configDir = os.path.expanduser('~/.nemu') if not os.path.isdir(self.configDir): os.mkdir(self.configDir) self.menuItems = self.loadConfig(self.menuFile, self.menuItems) self.favorites = self.loadConfig(self.favoritesFile, self.favorites) # Don't load directly into self.settings so we can add new default values as needed try: tempSettings = self.loadConfig(self.settingsFile, self.settings) for key, value in tempSettings.items(): self.settings[key] = value except SystemError: print('ERROR: Failed to load settings. You may need to run migrate-settings.') raise # This should never happen, but unfortunately bugs do, so clean up orphaned items. # We need to do this because these items won't show up in the UI, but may interfere with # merges if they duplicate something that is being merged in. self.menuItems[:] = [i for i in self.menuItems if i.parent == None or i.parent in self.menuItems] # Look for broken icon paths needSave = False for i in self.menuItems + self.favorites: if not os.path.exists(i.icon): i.findIcon() needSave = True if needSave: self.saveMenu() for i in self.menuItems: if not hasattr(i, 'imported'): i.imported = False self.setupUI() self.setContextMenuPolicy(Qt.ActionsContextMenu) self.createMenu(self) self.refresh(False) if len(self.menuItems) == 0: self.firstRun() self.show() self.keepaliveTimer = QTimer(self) self.keepaliveTimer.timeout.connect(self.keepalive) self.keepaliveTimer.start(60000) def initSettings(self): self.settings = dict() self.settings['width'] = 400 self.settings['height'] = 400 self.settings['quit'] = False self.settings['imported'] = [] self.settings['iconTheme'] = None def loadConfig(self, filename, default): if os.path.exists(filename): with open(filename, 'rb') as f: data = f.read().replace('PyQt4', 'PyQt5') return cPickle.loads(data) else: return default def setupUI(self): self.resize(self.settings['width'], self.settings['height']) self.setWindowFlags(Qt.FramelessWindowHint | Qt.CustomizeWindowHint | Qt.WindowStaysOnTopHint) #self.setWindowFlags(Qt.X11BypassWindowManagerHint) self.setWindowTitle('Nemu') self.setMouseTracking(True) iconPath = os.path.join(os.path.dirname(__file__), 'images') iconPath = os.path.join(iconPath, 'nemu.png') self.setWindowIcon(IconCache()[iconPath]) self.place() self.buttonListLayout = QVBoxLayout(self) self.setMargins(self.buttonListLayout) self.buttonLayout = QHBoxLayout() self.setMargins(self.buttonLayout) # Settings and Filter box self.filterLayout = QHBoxLayout() self.settingsButton = QPushButton() self.settingsButton.setIcon(QIcon(iconPath)) self.settingsButton.setMinimumHeight(35) self.settingsButton.clicked.connect(self.settingsClicked) self.filterLayout.addWidget(self.settingsButton, 0) self.filterLabel = QLabel("Filter") self.filterLayout.addWidget(self.filterLabel) self.filterBox = QLineEdit() self.filterBox.textChanged.connect(self.refresh) self.filterLayout.addWidget(self.filterBox) self.sizeGrip = QSizeGrip(self) self.sizeGrip.setMinimumSize(QSize(25, 25)) self.filterLayout.addWidget(self.sizeGrip, 0, Qt.AlignRight | Qt.AlignTop) self.buttonListLayout.addLayout(self.filterLayout) # Top buttons and labels self.backButton = QPushButton('Favorites') self.backButton.setMinimumHeight(35) self.backButton.clicked.connect(self.backClicked) self.buttonLayout.addWidget(self.backButton, 1) self.currentLabel = QLabel() self.currentLabel.setAlignment(Qt.AlignHCenter | Qt.AlignVCenter) self.buttonLayout.addWidget(self.currentLabel, 1) self.buttonListLayout.addLayout(self.buttonLayout, 0) # Menu item display self.listSplitter = QSplitter() self.buttonListLayout.addWidget(self.listSplitter, 1) self.leftList = ListWidget(self.clearListMouseOver) self.listSplitter.addWidget(self.leftList) self.rightList = ListWidget(self.clearListMouseOver) self.listSplitter.addWidget(self.rightList) # Has to be done after adding widgets to the splitter or the size will get reset again if 'splitterState' in self.settings: self.listSplitter.restoreState(self.settings['splitterState']) def setMargins(self, layout, margin = 0): layout.setSpacing(margin) layout.setContentsMargins(margin, margin, margin, margin) def createMenu(self, widget): addFavoriteAction = QAction('Add to Favorites', self) addFavoriteAction.triggered.connect(self.addFavoriteClicked) widget.insertAction(None, addFavoriteAction) addAction = QAction("New...", self) addAction.triggered.connect(self.newClicked) widget.insertAction(None, addAction) editAction = QAction("Edit...", self) editAction.triggered.connect(self.editClicked) widget.insertAction(None, editAction) deleteAction = QAction("Delete", self) deleteAction.triggered.connect(self.deleteClicked) widget.insertAction(None, deleteAction) def hideOrClose(self): if self.settings['quit']: self.close() else: self.hide() def closeEvent(self, event): self.saveSettings() def hideEvent(self, event): self.releaseMouse() self.saveSettings() def mouseMoveEvent(self, event): if self.hasMouse(): self.releaseMouse() def leaveEvent(self, event): # If we set holdOpen, it means that we've opened a dialog, so we shouldn't grab if not self.hasMouse(): self.grabMouse() def mousePressEvent(self, event): if not self.hasMouse(): self.hideOrClose() def hasMouse(self): return self.geometry().contains(QCursor.pos()) def saveSettings(self): self.settings['splitterState'] = self.listSplitter.saveState() self.settings['width'] = self.width() self.settings['height'] = self.height() with open(self.settingsFile, 'wb') as f: cPickle.dump(self.settings, f) def place(self): desktop = qApp.desktop() screenSize = desktop.availableGeometry(QCursor.pos()) self.move(screenSize.x(), screenSize.y() + screenSize.height() - self.height()) def newClicked(self): form = AddForm() self.holdOpen = True form.exec_() self.checkMouse() self.holdOpen = False if form.accepted: item = MenuItem() item.name = form.name item.command = form.command item.working = form.working item.folder = form.folder item.icon = form.icon item.findIcon() clicked = self.getClicked() if clicked: parent = clicked.item.parent elif self.leftList.mouseOver: if self.currentItem != None: parent = self.currentItem.parent else: parent = None else: parent = self.currentItem item.parent = parent self.menuItems.append(item) self.refresh() def editClicked(self): form = AddForm() clicked = self.getClicked() if clicked == None: return item = clicked.item form.name = item.name form.command = item.command form.working = item.working form.folder = item.folder form.icon = item.icon form.populateFields() self.holdOpen = True form.exec_() self.checkMouse() self.holdOpen = False if form.accepted: item.name = form.name item.command = form.command item.working = form.working item.folder = form.folder item.icon = form.icon item.imported = False item.findIcon() self.refresh() def checkMouse(self): if not self.hasMouse(): self.grabMouse() def deleteClicked(self): clicked = self.getClicked() if clicked == None: return self.delete(clicked.item) self.refresh() # Delete item and all of its children so we don't leave around orphaned items def delete(self, item): for i in self.menuItems: if i.parent == item: i.deleted = True if item in self.menuItems: item.deleted = True item.imported = False if item in self.favorites: self.favorites.remove(item) def addFavoriteClicked(self): newFavorite = copy.copy(self.getClicked().item) newFavorite.parent = None self.favorites.append(newFavorite) self.refresh() def getClicked(self): for i in self.allItems: if i.mouseOver: return i def clearMouseOver(self): for i in self.allItems: i.mouseOver = False def clearListMouseOver(self): self.leftList.mouseOver = False self.rightList.mouseOver = False def refresh(self, save = True): self.leftList.clear() self.rightList.clear() self.allItems = [] sortedLeft = [] sortedRight = [] self.updateFilter() if self.currentItem != None: currParent = self.currentItem.parent for i in self.menuItems: if i.parent == currParent and not i.deleted and i.matchedFilter: sortedLeft.append(i) else: for i in self.favorites: sortedLeft.append(i) for i in self.menuItems: if i.parent == self.currentItem and not i.deleted and i.matchedFilter: sortedRight.append(i) sortedLeft.sort(key = lambda x: x.name) sortedLeft.sort(key = lambda x: not x.folder) sortedRight.sort(key = lambda x: x.name) sortedRight.sort(key = lambda x: not x.folder) for i in sortedLeft: self.leftList.add(self.createItem(i)) for i in sortedRight: self.rightList.add(self.createItem(i)) if save: self.saveMenu() def saveMenu(self): # Save the current menu status with open(self.menuFile, 'wb') as f: cPickle.dump(self.menuItems, f) with open(self.favoritesFile, 'wb') as f: cPickle.dump(self.favorites, f) def createItem(self, item): newItem = ListItem(item, self.clearMouseOver) newItem.clicked.connect(self.itemClicked) self.allItems.append(newItem) return newItem def updateFilter(self): filterValue = str(self.filterBox.text()) for i in self.menuItems: i.checkFilter(filterValue) def itemClicked(self): sender = self.sender() if sender.item.folder: self.setCurrentItem(sender.item) self.refresh(False) else: flags = ['f', 'F', 'u', 'U', 'd', 'D', 'n', 'N', 'i', 'k', 'v', 'm'] command = sender.item.command for i in flags: command = command.replace('%' + i, '') # %c needs a proper value in some cases command = command.replace('%c', '"%s"' % sender.item.name) working = sender.item.working if not os.path.isdir(working): working = None # Need to redirect stdout and stderr so if the process writes something it won't fail with open(os.path.devnull, 'w') as devnull: Popen(command + '&', stdout=devnull, stderr=devnull, shell=True, cwd=working) self.hideOrClose() def backClicked(self): if self.currentItem: self.setCurrentItem(self.currentItem.parent) self.refresh(False) def setCurrentItem(self, item): self.currentItem = item if item != None: self.currentLabel.setText(item.name) if item.parent != None: self.backButton.setText(item.parent.name) else: self.backButton.setText('Favorites') else: self.currentLabel.setText('') self.backButton.setText('Favorites') def settingsClicked(self): form = SettingsForm(self) form.quitCheck.setChecked(self.settings['quit']) theme = self.settings.get('iconTheme') if theme: form.themeCombo.setCurrentIndex(form.themeCombo.findText(theme)) self.holdOpen = True form.exec_() self.checkMouse() self.holdOpen = False if form.accepted: self.settings['quit'] = form.quitCheck.isChecked() def firstRun(self): QMessageBox.information(self, 'First Time?', 'Your menu is currently empty. It is recommended that you import an existing menu file.') self.settingsClicked() def connectToRunning(self): self.socket = QLocalSocket() self.socket.connectToServer('nemuSocket') self.socket.waitForConnected(1000) if self.socket.state() == QLocalSocket.ConnectedState: print 'Server found' if self.socket.waitForReadyRead(3000): line = self.socket.readLine() print line else: print self.socket.errorString() sys.exit() else: print 'No server running' def handleConnection(self): import datetime print "Got connection", datetime.datetime.now() connection = self.server.nextPendingConnection() connection.write('connected') del connection self.setCurrentItem(None) self.filterBox.setText('') self.refresh(False) self.show() print "Showed", datetime.datetime.now() return # Call periodically to keep data resident in memory (hopefully) def keepalive(self): if self.isHidden(): self.refresh(False)
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: 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()))