pyqt send message to another instance

Code Example - pyqt send message to another instance

                
                        from PyQt5.QtCore import QSharedMemory, QTimer, QObject, pyqtSignal
from PyQt5.QtWidgets import QMessageBox, QWidget, QApplication

class SingleInstanceException(Exception):
    pass

class SharedMemoryReader(QObject):

    received = pyqtSignal(bytes)

    def __init__(self, key, parent = None):
        super().__init__(parent)

        memory = QSharedMemory(key)
        if not memory.create(1, QSharedMemory.ReadWrite):
            raise SingleInstanceException()
        
        self._memory = memory
        memory.lock()
        self.clearMemory()
        memory.unlock()

        # timer to poll shared memory for changes
        timer = QTimer()
        timer.timeout.connect(self.onTimeOut)
        timer.start(500)
        self._timer = timer

    def clearMemory(self):
        self._memory.data()[0] = b'0'
        
    def onTimeOut(self):
        memory = self._memory
        memory.lock()
        data = memory.data()[0]
        if data != b'0':
            self.received.emit(data)
            self.clearMemory()
        memory.unlock()

class SharedMemoryWriter(QObject):

    def __init__(self, key, parent = None):
        super().__init__(parent)
        memory = QSharedMemory(key)
        self._memory = memory
        
    def write(self, message):
        memory = self._memory
        if not memory.isAttached():
            memory.attach()
        memory.lock()
        memory.data()[0] = message
        memory.unlock()

if __name__ == "__main__":
    app = QApplication([])

    # guid to identify your application (some unique string)
    guid = "5c197822-e86a-4547-a4f1-dbb5087b962d"

    widget = QWidget()

    try:
        # First instance creates shared memory. 
        # If memory exists exception raised and it means that it's not first instance.
        reader = SharedMemoryReader(guid)
        reader.received.connect(lambda: QMessageBox.information(widget,"","Signal from another instance received"))
    except SingleInstanceException:
        # Second instance writes to memory (sends signal to first instance) and exits
        writer = SharedMemoryWriter(guid)
        writer.write(b'1')
        exit(0)
    
    # No exception raised - that means its first instance of application
    # Continue normally
    widget.show()

    app.exec_()