How to restore the QT window minimized into system tray from other process?



  • This is one feature in big system. We simplify the problem into sample code below. (Test Environment: Win7 64bit, python 2.7)

    In the sample, we can click "hide" to minimize the window into system tray with the taskbar button hidden.If we click the tray button, the hidden window can show again.

    We hope to implement the feature: when one instance has started and the window has been minimized into system tray, we start another instance(with the same script), then the new instance activates the old instance's window and show it back on the top.

    Our method:
    The new instance uses FindWindow API to get the window handle and then show it, the problem is that it fail to find the handle of old instance's window. Therefore we cannot locate the window handle to show it out again. We have used Spy++ to detect, there is no "MyWin" named window when the old instance is minimized into system tray.

    Can anybody help to find the solution to implement the feature?

    from PySide import QtGui, QtCore
    from PySide.QtCore import *
    from PySide.QtGui import *
    import sys
    import os
    import tempfile
    import win32gui
    
    # enable Ctrl-C to breakdown
    import signal
    signal.signal(signal.SIGINT, signal.SIG_DFL)
    
    # checkSingleton : code modifieed from tendo.SingletInstance
    def checkSingleton():
        
        basename = os.path.splitext(os.path.abspath(sys.argv[0]))[0].replace(
            "/", "-").replace(":", "").replace("\\", "-")  + '.lock'
        lockfile = os.path.normpath(tempfile.gettempdir() + '/' + basename)
            
        success = False
        try:
            if os.path.exists(lockfile):
                os.unlink(lockfile)
            fd = os.open(lockfile, os.O_CREAT | os.O_EXCL | os.O_RDWR)
            success = True
        except OSError:
            pass
                
        return success
        
    class MyWin(QWidget):
        def __init__(self):  
            super(MyWin, self).__init__()
            self.setWindowTitle("MyWin")
            self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowSystemMenuHint | Qt.WindowMinimizeButtonHint | Qt.WindowMaximizeButtonHint)
            self.tray = QtGui.QSystemTrayIcon(QtGui.QIcon("logo.png"), self)
            self.tray.activated.connect(self.trayClicked)
            self.tray.show()
            
            btn = QPushButton("Hide")
            btn.clicked.connect(self.onHide)
            btn2 = QPushButton("Close")
            btn2.clicked.connect(self.onClose)
            
            out = QVBoxLayout()
            out.addWidget(btn)
            out.addWidget(btn2)
            self.setLayout(out)
    
        def onHide(self):
            self.setWindowFlags(self.windowFlags() | Qt.Tool)
            self.showMinimized()
            
        def onClose(self):
            sys.exit()
            
        def showUp(self):
            self.setWindowFlags(self.windowFlags() & (~Qt.Tool))
            
            self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
            self.setWindowFlags(self.windowFlags() & ~Qt.WindowStaysOnTopHint)
            self.setWindowState(Qt.WindowActive)        
            self.show()
            
        def trayClicked(self, reason):
            if reason == QtGui.QSystemTrayIcon.Trigger:
                self.showUp()
                
    app = QtGui.QApplication(sys.argv)
    
    ret = checkSingleton()
    if ret:
        win= MyWin()
        win.setGeometry(100,100,300,300)
        win.show()
        app.exec_()
    else:
        print "One instance has already been running"
        hwnd = win32gui.FindWindow("QWidget","MyWin")  # < ==  Fail to find the handle of window to show it back
        if hwnd != 0:
            win32gui.SetForegroundWindow(hwnd)
            win32gui.ShowWindow(hwnd, 1)

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    From what you describe you should rather create bindings for the QtSingleApplication module and use that.

    It's typically a module used when you want to have only one instance of your application running.



  • Thanks, SGaist.
    QtSingleApplicaiton is an alternative solution to singleton , I will make a try.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.