class MainWindow(QWidget): def __init__(self, parent = None): super(MainWindow, self).__init__(parent) self.shareMemory = QSharedMemory('QSharedMemoryExample') self.ui = MessageSender() self.setWindowTitle("simple communication demo") self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.ui) self.setFixedSize(500, 600) self.setLayout(self.mainLayout) def sendMessage(self): textbuf = QBuffer() textbuf.open(QBuffer.ReadWrite) messageText = QDataStream(textbuf) messageText << self.ui.messageBox.text size = textbuf.size() if not self.shareMemory.create(size): return size = min(self.shareMemory.size(), size) self.sharedMemory.lock()
def __init__(self, key='memory_condition_key'): self._shm = QSharedMemory(key) if not self._shm.attach(): if not self._shm.create(1): raise RuntimeError('error creating shared memory: %s' % self._shm.errorString()) self.condition = False
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)
class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.shareMemory = QSharedMemory('QSharedMemoryExample') self.ui = MessageSender() self.setWindowTitle("simple communication demo") self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.ui) self.setFixedSize(500, 600) self.setLayout(self.mainLayout) def sendMessage(self): textbuf = QBuffer() textbuf.open(QBuffer.ReadWrite) messageText = QDataStream(textbuf) messageText << self.ui.messageBox.text size = textbuf.size() if not self.shareMemory.create(size): return size = min(self.shareMemory.size(), size) self.sharedMemory.lock()
def is_already_running(self): """ Look to see if AppFTD is already running and ask if a 2nd instance is to be started. """ self.shared_memory = QSharedMemory('AppFTD') if self.shared_memory.attach(): log.error("It's already running") return True else: self.shared_memory.create(1) return False
def __init__(self, parent=None): super(MainWindow, self).__init__(parent) self.shareMemory = QSharedMemory('QSharedMemoryExample') self.ui = MessageSender() self.setWindowTitle("simple communication demo") self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.ui) self.setFixedSize(500, 600) self.setLayout(self.mainLayout)
def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.sharedMemory = QSharedMemory('QSharedMemoryExample') self.ui = Ui_Dialog() self.ui.setupUi(self) self.ui.loadFromFileButton.clicked.connect(self.loadFromFile) self.ui.loadFromSharedMemoryButton.clicked.connect(self.loadFromMemory) self.setWindowTitle("SharedMemory Example")
def __init__(self, parent=None): super(ProducerDialog, self).__init__(parent) self.ui = Ui_Dialog() self.ui.setupUi(self) # We only allow one image to be put into the shared memory (otherwise we would need to # create a dedicated data structure within the SHARED memory and access it from Python and # C++ appropriately). Also note that "Open" and "Create" have very different semantics (see # docs) and we use "Create" to always create a "fresh" semaphore to not cause undesired # blocking/stalls, see also https://doc.qt.io/qt-5/qsystemsemaphore.html if CONSUMER == 0: self.ui.loadFromFileButton.clicked.connect(self.load_from_file) self.ui.loadFromSharedMemoryButton.setEnabled(False) self.setWindowTitle("Shared Memory Producer: Python Example") from prodcon_ipc.producer_ipc import ProducerIPC self.producer_ipc = ProducerIPC(UNIQUE_SHARED_MEMORY_NAME, SHARED_MEMORY_KEY_FILE) else: self.ui.loadFromSharedMemoryButton.clicked.connect( self.load_from_memory) self.ui.loadFromFileButton.setEnabled(False) self.setWindowTitle("Shared Memory Consumer: Python Example") from prodcon_ipc.consumer_ipc import ConsumerIPC self.consumer_ipc = ConsumerIPC(UNIQUE_SHARED_MEMORY_NAME, SHARED_MEMORY_KEY_FILE) if SHARED_STRUCT == 1: self.shmem_config = QSharedMemory('shared_struct_test') if self.shmem_config.isAttached() or self.shmem_config.attach(): if self.shmem_config.lock(): counter, stop_flag, file_name = struct.unpack( STRUCT_FORMAT, self.shmem_config.constData()) logzero.logger.debug( "Shared memory struct read: counter=" + str(counter) + ", stop_flag=" + str(stop_flag) + ", file_name=" + file_name) self.shmem_config.unlock() else: logzero.logger.error("unable to lock " + self.shmem_config.key()) # Note: if both processes detach from the memory, it gets deleted so that attach() fails. That's why we # simply never detach (HERE). Depending on the app design, there may be a better solution. #self.shmem_config.detach() else: logzero.logger.error("unable to attach " + self.shmem_config.key())
def __init__(self, *args, **kwargs): super(SharedApplication, self).__init__(*args, **kwargs) self._running = False key = "SharedApplication" + __version__ self._memory = QSharedMemory(key, self) isAttached = self._memory.isAttached() print("isAttached", isAttached) if isAttached: # 如果进程附加在共享内存上 detach = self._memory.detach() # 取消进程附加在共享内存上 print("detach", detach) if self._memory.create( 1) and self._memory.error() != QSharedMemory.AlreadyExists: # 创建共享内存,如果创建失败,则说明已经创建,否则未创建 print("create ok") else: print("create failed") self._running = True del self._memory
def __init__(self, argv, key): super().__init__(argv) QSharedMemory(key).attach() self._memory = QSharedMemory(self) self._memory.setKey(key) if self._memory.attach(): self._running = True else: self._running = False if not self._memory.create(1): raise RuntimeError(self._memory.errorString()) self._key = key self._timeout = 1000 self._server = QLocalServer(self) if not self.isRunning(): self._server.newConnection.connect(self.handleMessage) self._server.listen(self._key) self._settings = QSettings("Raul Sangonzalo", "Musician Suite") # self._settings.setValue("currentDatabase", None) # testing purposes self.initialPrompt = InitialPrompt() self.initialPrompt.databaseSelected.connect(self.reloadInit)
def single_instance_lock(): sharedMemory = QSharedMemory( "77rWEV37vupNhQs6ktDREthqSciyV77OYrqPBSwV755JFIhl9iOywB7G5DkAKU8Y") if sharedMemory.attach(QSharedMemory.ReadOnly): sharedMemory.detach() return None if sharedMemory.create(1): return sharedMemory return None
def accept(self): logging.debug('connection accepted') conn = self.server.nextPendingConnection() conn.waitForReadyRead() key = str(conn.read(36).decode()) memory = QSharedMemory() memory.setKey(key) memory.attach() logging.debug('attached to memory %s with size %s'%(key, memory.size())) atexit.register(memory.detach) self.conns.append(conn) self.shared_mems.append(memory) conn.readyRead.connect(lambda: self.read_from(conn, memory)) conn.disconnected.connect(memory.detach) conn.write(b'ok')
def instance_check(app): app.instance_check = QSharedMemory(f'{APP_NAME} - Instance Check') if not app.instance_check.create(4, QSharedMemory.ReadWrite): # Already running. Read the PID from the shared memory and return it. app.instance_check.attach(QSharedMemory.ReadOnly) app.instance_check.lock() view = memoryview(app.instance_check.data()) existing_pid = struct.unpack('=i', view[:4])[0] app.instance_check.unlock() return existing_pid # Write the current PID into the shared memory object. pid = app.applicationPid() app.instance_check.lock() app.instance_check.data()[:4] = memoryview(struct.pack('=i', pid)) app.instance_check.unlock() return 0
def single_instance_lock(currency): key = hashlib.sha256(currency.encode('utf-8') + "77rWEV37vupNhQs6ktDREthqSciyV77OYrqPBSwV755JFIhl9iOywB7G5DkAKU8Y".encode('utf-8'))\ .hexdigest() sharedMemory = QSharedMemory(key) if sharedMemory.attach(QSharedMemory.ReadOnly): sharedMemory.detach() return None if sharedMemory.create(1): return sharedMemory return None
def receiveMessage(self): stream = QTextStream(self.conn) if stream.atEnd(): return data = stream.readAll() for json_str in data.split("\n")[:-1]: obj = json.loads(json_str) msgType = obj["type"] if msgType == self.TYPE_NOTIFICATION: self.log("Notification Received. code: {0}".format( obj["params"].get("code"))) if obj["params"].get("code") == self.N_DATA_RECEIVED: memKey = obj["params"]["memoryKey"] mem = self._mem[memKey] if mem.isAttached(): mem.detach() self.log( "Shared memory detached: key={0}".format(memKey)) del self._mem[memKey] else: self.notified.emit(obj["params"]) elif msgType == self.TYPE_REQUEST: self.log( "Request Received. dataType: {0}, renderId: {1}".format( obj["params"].get("dataType"), obj["params"].get("renderId"))) self.requestReceived.emit(obj["params"]) elif msgType == self.TYPE_RESPONSE: self.log( "Response Received. dataType: {0}, renderId: {1}".format( obj["meta"].get("dataType"), obj["meta"].get("renderId"))) mem = QSharedMemory(obj["memoryKey"]) if not mem.attach(QSharedMemory.ReadOnly): self.log( "Cannot attach this process to the shared memory segment: {0}" .format(mem.errorString())) return size = mem.size() self.log("Size of memory segment is {0} bytes.".format(size)) mem.lock() ba = QByteArray() buffer = QBuffer(ba) buffer.setData(mem.constData()) mem.unlock() mem.detach() data = ba.data() lines = data.split(b"\n") for line in lines[:5]: self.log(line[:76]) if len(lines) > 5: self.log("--Total {0} Lines Received--".format(len(lines))) self.notify({ "code": self.N_DATA_RECEIVED, "memoryKey": obj["memoryKey"] }) self.responseReceived.emit(data, obj["meta"])
for tunnel in self.tunnels: name = tunnel.name.text() data[name] = tunnel.tunnelconfig.as_dict() timestamp = int(time.time()) shutil.copy(CONF_FILE, F"{CONF_FILE}-{timestamp}") with open(CONF_FILE, "w") as fp: yaml.dump(data, fp) backup_configs = glob.glob(F"{CONF_FILE}-*") if len(backup_configs) > 10: for config in sorted(backup_configs, reverse=True)[10:]: os.remove(config) event.accept() if __name__ == '__main__': app = QApplication(sys.argv) sm = QSharedMemory("3866273d-f4d5-4bf3-b27b-772ca7915a61") if not sm.create(1): mb = QMessageBox() mb.setIcon(QMessageBox.Information) mb.setText("SSH Tunnel Manager is already running") mb.setWindowTitle("Oops!") mb.setStandardButtons(QMessageBox.Ok) mb.show() else: tm = TunnelManager() sys.exit(app.exec_())
class MusicianSuite(QApplication): signalReceived = pyqtSignal(object) def __init__(self, argv, key): super().__init__(argv) QSharedMemory(key).attach() self._memory = QSharedMemory(self) self._memory.setKey(key) if self._memory.attach(): self._running = True else: self._running = False if not self._memory.create(1): raise RuntimeError(self._memory.errorString()) self._key = key self._timeout = 1000 self._server = QLocalServer(self) if not self.isRunning(): self._server.newConnection.connect(self.handleMessage) self._server.listen(self._key) self._settings = QSettings("Raul Sangonzalo", "Musician Suite") # self._settings.setValue("currentDatabase", None) # testing purposes self.initialPrompt = InitialPrompt() self.initialPrompt.databaseSelected.connect(self.reloadInit) def isRunning(self): return self._running def handleMessage(self): socket = self._server.nextPendingConnection() if socket.waitForReadyRead(self._timeout): self.signalReceived.emit( socket.readAll().data().decode('utf-8')) socket.disconnectFromServer() else: Qt.QDebug(socket.errorString()) 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 init(self): """True initiation of the App, if only one instance""" if self._settings.value("currentDatabase") == None: self.initialPrompt.show() else: # check in case user moves the location of db location = self._settings.value("currentDatabase") print("------>", location) if not os.path.exists(location): self.initialPrompt.show() else: self.mainWindow = MusicMainWindow() # mac madness os.chdir(os.path.dirname(os.path.abspath(__file__))) resourcesPath = os.getcwd() resourcesPath = os.path.join(resourcesPath, "resources") if not os.path.exists(resourcesPath): os.mkdir(resourcesPath) self.MAIN_ICON = QIcon(os.path.join(resourcesPath, "test.ico")) self.ICON0 = QIcon( QPixmap(os.path.join(resourcesPath, "icon0.png"))) self.ICON1 = QIcon( QPixmap(os.path.join(resourcesPath, "icon1.png"))) self.RECORD_ICON = QIcon( QPixmap(os.path.join(resourcesPath, "record.png"))) self.widget = QWidget() self.trayIcon = QSystemTrayIcon(self.MAIN_ICON, self.widget) self.trayIcon.setToolTip("Musician Suite") self.trayIconMenu = QMenu() self.songListAction = QAction(self.ICON0, "Song List") self.recordIdeasAction = QAction(self.ICON1, "Recorded Ideas") self.recordAction = QAction(self.RECORD_ICON, "Record now!") self.exitAction = QAction("Exit") self.trayIconMenu.addAction(self.songListAction) self.trayIconMenu.addAction(self.recordIdeasAction) self.trayIconMenu.addAction(self.recordAction) self.trayIconMenu.addAction(self.exitAction) self.trayIcon.setContextMenu(self.trayIconMenu) self.trayIcon.show() self.trayIcon.activated.connect(self.iconDoubleClickMain) self.trayIconMenu.triggered.connect(self.messagePopup) self.mainWindow.stackedWidget.setCurrentIndex(0) self.signalReceived.connect(self.showMainWindow) self.mainWindow.show() def showMainWindow(self): self.mainWindow.show() def reloadInit(self): print("I am in reload Init") self.initialPrompt.hide() self.init() def iconDoubleClickMain(self, reason): if reason == QSystemTrayIcon.DoubleClick: self.mainWindow.stackedWidget.setCurrentIndex(0) self.mainWindow.show() def messagePopup(self, action): """Pressing the menu and toast """ if action == self.songListAction: if not self.mainWindow.isVisible(): self.mainWindow.stackedWidget.setCurrentIndex(0) self.mainWindow.show() elif action == self.recordIdeasAction: if not self.mainWindow.isVisible(): self.mainWindow.stackedWidget.setCurrentIndex(1) self.mainWindow.show() elif action == self.recordAction: self.startRecordingHook() else: self.exit() def startRecordingHook(self): self.mainWindow.stackedWidget.setCurrentIndex(1) self.mainWindow.show() listRows = self.mainWindow.recordIdeas.recordedIdeasListWidget.count() print(listRows) self.mainWindow.recordIdeas.recordedIdeasListWidget.setCurrentRow( listRows-1) self.mainWindow.recordIdeas.record()
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 ProducerDialog(QDialog): def __init__(self, parent=None): super(ProducerDialog, self).__init__(parent) self.ui = Ui_Dialog() self.ui.setupUi(self) # We only allow one image to be put into the shared memory (otherwise we would need to # create a dedicated data structure within the SHARED memory and access it from Python and # C++ appropriately). Also note that "Open" and "Create" have very different semantics (see # docs) and we use "Create" to always create a "fresh" semaphore to not cause undesired # blocking/stalls, see also https://doc.qt.io/qt-5/qsystemsemaphore.html if CONSUMER == 0: self.ui.loadFromFileButton.clicked.connect(self.load_from_file) self.ui.loadFromSharedMemoryButton.setEnabled(False) self.setWindowTitle("Shared Memory Producer: Python Example") from prodcon_ipc.producer_ipc import ProducerIPC self.producer_ipc = ProducerIPC(UNIQUE_SHARED_MEMORY_NAME, SHARED_MEMORY_KEY_FILE) else: self.ui.loadFromSharedMemoryButton.clicked.connect( self.load_from_memory) self.ui.loadFromFileButton.setEnabled(False) self.setWindowTitle("Shared Memory Consumer: Python Example") from prodcon_ipc.consumer_ipc import ConsumerIPC self.consumer_ipc = ConsumerIPC(UNIQUE_SHARED_MEMORY_NAME, SHARED_MEMORY_KEY_FILE) if SHARED_STRUCT == 1: self.shmem_config = QSharedMemory('shared_struct_test') if self.shmem_config.isAttached() or self.shmem_config.attach(): if self.shmem_config.lock(): counter, stop_flag, file_name = struct.unpack( STRUCT_FORMAT, self.shmem_config.constData()) logzero.logger.debug( "Shared memory struct read: counter=" + str(counter) + ", stop_flag=" + str(stop_flag) + ", file_name=" + file_name) self.shmem_config.unlock() else: logzero.logger.error("unable to lock " + self.shmem_config.key()) # Note: if both processes detach from the memory, it gets deleted so that attach() fails. That's why we # simply never detach (HERE). Depending on the app design, there may be a better solution. #self.shmem_config.detach() else: logzero.logger.error("unable to attach " + self.shmem_config.key()) def load_from_file(self): # producer slot self.ui.label.setText("Select an image file") file_name, t = QFileDialog.getOpenFileName(self, None, None, "Images (*.png *.jpg)") if not file_name: return image = QImage() if not image.load(file_name): self.ui.label.setText( "Selected file is not an image, please select another.") return self.ui.label.setPixmap(QPixmap.fromImage(image)) # Get the image data: buf = QBuffer() buf.open(QBuffer.ReadWrite) out = QDataStream(buf) out << image try: from prodcon_ipc.producer_ipc import ScopedProducer with ScopedProducer(self.producer_ipc, buf.size()) as sp: # Copy image data from buf into shared memory area: sp.data()[:sp.size()] = buf.data().data()[:sp.size()] except Exception as err: self.ui.label.setText(str(err)) if SHARED_STRUCT == 1: # Read from shared memory, increase value and write it back: if self.shmem_config.isAttached() or self.shmem_config.attach(): if self.shmem_config.lock(): counter, stop_flag, _ = struct.unpack( STRUCT_FORMAT, self.shmem_config.constData()) data = struct.pack(STRUCT_FORMAT, counter + 1, stop_flag, str(os.path.basename(file_name)[:30])) size = min(struct.calcsize(STRUCT_FORMAT), self.shmem_config.size()) self.shmem_config.data()[:size] = data[:size] self.shmem_config.unlock() if stop_flag: # stop producing? logzero.logger.info( "Consumer requested to stop the production.") sys.exit(0) else: logzero.logger.error("unable to lock " + self.shmem_config.key()) #self.shmem_config.detach() else: logzero.logger.error("unable to attach " + self.shmem_config.key()) def load_from_memory(self): # consumer slot buf = QBuffer() ins = QDataStream(buf) image = QImage() if True: # first variant (much simpler / shorter, more robust) try: from prodcon_ipc.consumer_ipc import ScopedConsumer with ScopedConsumer(self.consumer_ipc) as sc: buf.setData(sc.data()) buf.open(QBuffer.ReadOnly) ins >> image except Exception as err: self.ui.label.setText(str(err)) else: # second variant, using begin()...end() manually try: data = self.consumer_ipc.begin() except RuntimeError as err: self.ui.label.setText(str(err)) return # Read from the shared memory: try: buf.setData(data) buf.open(QBuffer.ReadOnly) ins >> image except Exception as err: logzero.logger.error(str(err)) try: self.consumer_ipc.end() except RuntimeError as err: self.ui.label.setText(str(err)) return if not image.isNull(): self.ui.label.setPixmap(QPixmap.fromImage(image)) else: logzero.logger.error("Image data was corrupted.")
class MemoryCondition: def __init__(self, key='memory_condition_key'): self._shm = QSharedMemory(key) if not self._shm.attach(): if not self._shm.create(1): raise RuntimeError('error creating shared memory: %s' % self._shm.errorString()) self.condition = False def __enter__(self): self._shm.lock() if self._shm.data()[0] == b'\x00': self.condition = True self._shm.data()[0] = b'\x01' self._shm.unlock() return self.condition def __exit__(self, exc_type, exc_value, traceback): if self.condition: self._shm.lock() self._shm.data()[0] = b'\x00' self._shm.unlock()
class Dialog(QDialog): """ This class is a simple example of how to use QSharedMemory. It is a simple dialog that presents a few buttons. Run the executable twice to create two processes running the dialog. In one of the processes, press the button to load an image into a shared memory segment, and then select an image file to load. Once the first process has loaded and displayed the image, in the second process, press the button to read the same image from shared memory. The second process displays the same image loaded from its new location in shared memory. The class contains a data member sharedMemory, which is initialized with the key "QSharedMemoryExample" to force all instances of Dialog to access the same shared memory segment. The constructor also connects the clicked() signal from each of the three dialog buttons to the slot function appropriate for handling each button. """ def __init__(self, parent = None): super(Dialog, self).__init__(parent) self.sharedMemory = QSharedMemory('QSharedMemoryExample') self.ui = Ui_Dialog() self.ui.setupUi(self) self.ui.loadFromFileButton.clicked.connect(self.loadFromFile) self.ui.loadFromSharedMemoryButton.clicked.connect(self.loadFromMemory) self.setWindowTitle("SharedMemory Example") def loadFromFile(self): """ This slot function is called when the "Load Image From File..." button is pressed on the firs Dialog process. First, it tests whether the process is already connected to a shared memory segment and, if so, detaches from that segment. This ensures that we always start the example from the beginning if we run it multiple times with the same two Dialog processes. After detaching from an existing shared memory segment, the user is prompted to select an image file. The selected file is loaded into a QImage. The QImage is displayed in the Dialog and streamed into a QBuffer with a QDataStream. Next, it gets a new shared memory segment from the system big enough to hold the image data in the QBuffer, and it locks the segment to prevent the second Dialog process from accessing it. Then it copies the image from the QBuffer into the shared memory segment. Finally, it unlocks the shared memory segment so the second Dialog process can access it. After self function runs, the user is expected to press the "Load Image from Shared Memory" button on the second Dialog process. """ if self.sharedMemory.isAttached(): self.detach() self.ui.label.setText("Select an image file") fileName, _ = QFileDialog.getOpenFileName(self, None, None, "Images (*.png *.xpm *.jpg)") image = QImage() if not image.load(fileName): self.ui.label.setText( "Selected file is not an image, please select another.") return self.ui.label.setPixmap(QPixmap.fromImage(image)) # Load into shared memory. buf = QBuffer() buf.open(QBuffer.ReadWrite) out = QDataStream(buf) out << image size = buf.size() if not self.sharedMemory.create(size): self.ui.label.setText("Unable to create shared memory segment.") return size = min(self.sharedMemory.size(), size) self.sharedMemory.lock() # Copy image data from buf into shared memory area. self.sharedMemory.data()[:] = buf.data().data() self.sharedMemory.unlock() def loadFromMemory(self): """ This slot function is called in the second Dialog process, when the user presses the "Load Image from Shared Memory" button. First, it attaches the process to the shared memory segment created by the first Dialog process. Then it locks the segment for exclusive access, copies the image data from the segment into a QBuffer, and streams the QBuffer into a QImage. Then it unlocks the shared memory segment, detaches from it, and finally displays the QImage in the Dialog. """ if not self.sharedMemory.attach(): self.ui.label.setText( "Unable to attach to shared memory segment.\nLoad an " "image first.") return buf = QBuffer() ins = QDataStream(buf) image = QImage() self.sharedMemory.lock() buf.setData(self.sharedMemory.constData()) buf.open(QBuffer.ReadOnly) ins >> image self.sharedMemory.unlock() self.sharedMemory.detach() self.ui.label.setPixmap(QPixmap.fromImage(image)) def detach(self): """ This private function is called by the destructor to detach the process from its shared memory segment. When the last process detaches from a shared memory segment, the system releases the shared memory. """ if not self.sharedMemory.detach(): self.ui.label.setText("Unable to detach from shared memory.")
class Dialog(QDialog): """ This class is a simple example of how to use QSharedMemory. It is a simple dialog that presents a few buttons. Run the executable twice to create two processes running the dialog. In one of the processes, press the button to load an image into a shared memory segment, and then select an image file to load. Once the first process has loaded and displayed the image, in the second process, press the button to read the same image from shared memory. The second process displays the same image loaded from its new location in shared memory. The class contains a data member sharedMemory, which is initialized with the key "QSharedMemoryExample" to force all instances of Dialog to access the same shared memory segment. The constructor also connects the clicked() signal from each of the three dialog buttons to the slot function appropriate for handling each button. """ def __init__(self, parent=None): super(Dialog, self).__init__(parent) self.sharedMemory = QSharedMemory('QSharedMemoryExample') self.ui = Ui_Dialog() self.ui.setupUi(self) self.ui.loadFromFileButton.clicked.connect(self.loadFromFile) self.ui.loadFromSharedMemoryButton.clicked.connect(self.loadFromMemory) self.setWindowTitle("SharedMemory Example") def loadFromFile(self): """ This slot function is called when the "Load Image From File..." button is pressed on the firs Dialog process. First, it tests whether the process is already connected to a shared memory segment and, if so, detaches from that segment. This ensures that we always start the example from the beginning if we run it multiple times with the same two Dialog processes. After detaching from an existing shared memory segment, the user is prompted to select an image file. The selected file is loaded into a QImage. The QImage is displayed in the Dialog and streamed into a QBuffer with a QDataStream. Next, it gets a new shared memory segment from the system big enough to hold the image data in the QBuffer, and it locks the segment to prevent the second Dialog process from accessing it. Then it copies the image from the QBuffer into the shared memory segment. Finally, it unlocks the shared memory segment so the second Dialog process can access it. After self function runs, the user is expected to press the "Load Image from Shared Memory" button on the second Dialog process. """ if self.sharedMemory.isAttached(): self.detach() self.ui.label.setText("Select an image file") fileName, _ = QFileDialog.getOpenFileName( self, None, None, "Images (*.png *.xpm *.jpg)") image = QImage() if not image.load(fileName): self.ui.label.setText( "Selected file is not an image, please select another.") return self.ui.label.setPixmap(QPixmap.fromImage(image)) # Load into shared memory. buf = QBuffer() buf.open(QBuffer.ReadWrite) out = QDataStream(buf) out << image size = buf.size() if not self.sharedMemory.create(size): self.ui.label.setText("Unable to create shared memory segment.") return size = min(self.sharedMemory.size(), size) self.sharedMemory.lock() # Copy image data from buf into shared memory area. self.sharedMemory.data()[:] = buf.data().data() self.sharedMemory.unlock() def loadFromMemory(self): """ This slot function is called in the second Dialog process, when the user presses the "Load Image from Shared Memory" button. First, it attaches the process to the shared memory segment created by the first Dialog process. Then it locks the segment for exclusive access, copies the image data from the segment into a QBuffer, and streams the QBuffer into a QImage. Then it unlocks the shared memory segment, detaches from it, and finally displays the QImage in the Dialog. """ if not self.sharedMemory.attach(): self.ui.label.setText( "Unable to attach to shared memory segment.\nLoad an " "image first.") return buf = QBuffer() ins = QDataStream(buf) image = QImage() self.sharedMemory.lock() buf.setData(self.sharedMemory.constData()) buf.open(QBuffer.ReadOnly) ins >> image self.sharedMemory.unlock() self.sharedMemory.detach() self.ui.label.setPixmap(QPixmap.fromImage(image)) def detach(self): """ This private function is called by the destructor to detach the process from its shared memory segment. When the last process detaches from a shared memory segment, the system releases the shared memory. """ if not self.sharedMemory.detach(): self.ui.label.setText("Unable to detach from shared memory.")
class AppFTD(QtWidgets.QApplication): """ The core application class. This class inherits from Qt's QApplication class in order to provide the core of the application. """ welcome_message = 'This application is aimed to provide a local (without Internet connection) way to users to ' \ 'work with Tabular data. \n\nIt has been developed from scratch and may contains ' \ 'bugs. \nDon\'t hesitate to send any report if you find a bug while using the program.' welcome_title = 'Welcome to the Application' modify_style = pyqtSignal() def __init__(self, parent=None): super(AppFTD, self).__init__(parent) Registry.create() # self.style = 0 self.modify_style.connect(self.change_style) # Initialize language manager LanguageManager(language='en_US') # Add predefined fonts #QFontDatabase.addApplicationFont(":/fonts/besmellah.ttf") QFontDatabase.addApplicationFont(":/fonts/capsuula.ttf") QFontDatabase.addApplicationFont(":/fonts/ubuntu.ttf") # Set stylesheet as Qt resource stylesheet = QFile(":/styles/default.css") stylesheet.open(QFile.ReadOnly | QFile.Text) self.stylesheet = QTextStream(stylesheet).readAll() self.setStyleSheet(self.stylesheet) self.setApplicationDisplayName("AppFTD") self.setApplicationName("AppFTD") self.setEffectEnabled(Qt.UI_AnimateCombo, False) self.setAttribute(Qt.AA_UseHighDpiPixmaps, True) Registry().register_signal("change_style", self.modify_style) def change_style(self): """ Change stylesheet. :return: """ pass # if self.style == 0: # self.setStyleSheet(open("resources/styles/white.css").read()) # self.style = 1 # else: # self.setStyleSheet(open("resources/styles/default.css").read()) # self.style = 0 def exec_(self): """ Override exec method to allow the shared memory to be released on exit """ result = QtWidgets.QApplication.exec_() # This function seems to cause problem in Ubuntu Linux because shared memory is not released. self.shared_memory.detach() return result def run(self): """ Run the AppFTD application.x """ activate_first_notification = False # First time checks in settings has_run_wizard = Settings().value('general_settings/wizard_runned') if not has_run_wizard: first_wizard = Wizard(parent=None) if first_wizard.exec_() == QtWidgets.QDialog.Accepted: Settings().setValue('general_settings/wizard_runned', 1) # Create the first notification only after wizard has been completed activate_first_notification = True elif first_wizard.was_cancelled: QCoreApplication.exit() sys.exit() # Show the SplashScreen show_splash = Settings().value('general_settings/splashscreen') if show_splash: splash = SplashScreen() splash.start_splashscreen.emit() # Start the main app window self.global_frame = GlobalFrame() # Make sure Qt really display the splash screen self.processEvents() self.global_frame.repaint() self.processEvents() Registry().execute('__application_init__') Registry().execute('__application_post_init__') self.processEvents() self.global_frame.show() # Show first notification program if activate_first_notification: WelcomeNotification(self.global_frame).notify( WelcomeNotification.OK, self.welcome_message, self.welcome_title, button_text='OK') if show_splash: # now kill the splashscreen splash.finish(self.global_frame) log.debug('Splashscreen closed') # Need to implement update checker # update_check = Settings().value('general_settings/update_check') # if update_check: # process return self.exec_() def is_already_running(self): """ Look to see if AppFTD is already running and ask if a 2nd instance is to be started. """ self.shared_memory = QSharedMemory('AppFTD') if self.shared_memory.attach(): log.error("It's already running") return True else: self.shared_memory.create(1) return False def set_busy_cursor(self): """ Sets the Busy Cursor for the Application """ self.setOverrideCursor(Qt.BusyCursor) self.processEvents() def set_normal_cursor(self): """ Sets the Normal Cursor for the Application """ self.restoreOverrideCursor() self.processEvents()
# from tensorflow.keras.applications import ResNet50 # from tensorflow.keras.preprocessing import image # from tensorflow.keras.applications.resnet50 import preprocess_input, decode_predictions SIZE = 224 CHANNELS = 3 #model = ResNet50(weights="imagenet") from PyQt5.QtCore import QSharedMemory,QBuffer import numpy as np from matplotlib import pyplot as plt import cv2 mem = QSharedMemory("image4") mem.attach() while True: mem.lock() t = np.array(mem.constData().asarray()) n_t = t[0:SIZE*SIZE*CHANNELS] plt.imshow(n_t.reshape((SIZE,SIZE,-1))) cv2.imwrite("test123.png",n_t.reshape((SIZE,SIZE,-1))) mem.unlock() break mem.unlock(); mem.detach(); #del model
def respond(self, byteArray, meta=None): if not self.conn: return False self.log("Sending Response. dataType: {0}, renderId: {1}".format( meta.get("dataType"), meta.get("renderId"))) obj = {"type": self.TYPE_RESPONSE, "meta": meta or {}} memKey = self.nextMemoryKey() obj["memoryKey"] = memKey # TODO: check that the memory segment is not used # store data in shared memory mem = QSharedMemory(memKey) if mem.isAttached(): mem.detach() if not mem.create(len(byteArray)): self.log(mem.errorString()) return False self.log("Shared memory created: {0}, {1} bytes".format( memKey, len(byteArray))) mem.lock() try: ctypes.memmove(int(mem.data()), byteArray, len(byteArray)) finally: mem.unlock() self._mem[memKey] = mem self.conn.write(json.dumps(obj).encode("utf-8") + b"\n") self.conn.flush() return True
def __init__(self, parent = None): super(Dialog, self).__init__(parent) self.sharedMemory = QSharedMemory('QSharedMemoryExample') self.ui = Ui_Dialog() self.ui.setupUi(self) self.ui.loadFromFileButton.clicked.connect(self.loadFromFile) self.ui.loadFromSharedMemoryButton.clicked.connect(self.loadFromMemory) self.setWindowTitle("SharedMemory Example")
def __init__(self, parent = None): super(MainWindow, self).__init__(parent) self.shareMemory = QSharedMemory('QSharedMemoryExample') self.ui = MessageSender() self.setWindowTitle("simple communication demo") self.mainLayout = QVBoxLayout() self.mainLayout.addWidget(self.ui) self.setFixedSize(500, 600) self.setLayout(self.mainLayout)