1

How to view or active a application window exists in task-bar When the user tries to run it again.

For Example: I have already opened MyApp application and that is already existed on task-bar and want to maximize the MyApp ,If I try to open it again via the application icon on the desktop or from the start menu.

I have this script yet:

def process():
    import psutil
    PROCNAME = 'MyApp.exe'
    for proc in psutil.process_iter():
        try:
            if proc.name().lower() == PROCNAME.lower():
                
                return
        except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
            pass
    MainThred = QApplication([])
    MainGUI = MainWindow()
    MainGUI.show()
    sysExit(MainThred.exec_())
if __name__ == "__main__":
    process()
eyllanesc
  • 235,170
  • 19
  • 170
  • 241

1 Answers1

2

You describe common pattern known as single instance of application. Your second instance should be aware of first instance and send a signal to first instance to show window and then exit immediately. So you need some form of interprocess communication (IPC). It can be achieved using tcp socket or file handle or shared memory.

SingleInstance implementation using shared memory:

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_()
mugiseyebrows
  • 4,138
  • 1
  • 14
  • 15