문제

I am trying to launch a system tray menu after successful login. I have 2 QtUi screens and the rest is just python code. The login dialog comes first and I want to hide this after login and show the system tray menu. Here is my code so far:

Note: UI_Login is a dialog from QtDesigner

1. System tray ui

from PyQt4 import QtGui

class SystemTrayIcon(QtGui.QSystemTrayIcon):

    def __init__(self, icon, parent=None):
        QtGui.QSystemTrayIcon.__init__(self, parent)
        menu = QtGui.QMenu(parent)        
        self.exitAction = menu.addAction("Exit")
        self.helpAction = menu.addAction("Help")
        self.setIcon(icon)
        self.setContextMenu(menu)

2. Login function. Calling SystemTrayIcon

import sys
from PyQt4 import QtGui, QtCore
from modules.ui.login_ui import Ui_Login
from modules.ui.menu_ui import SystemTrayIcon
from api.auth import doLogin

class Login(QtGui.QDialog):
    """
    Login user via the api
    Links the gui and the app functionality
    Logged user token is saved for further processing
    """
    def __init__(self, parent = None):
        QtGui.QDialog.__init__(self, parent)
        self.ui = Ui_Login()
        self.ui.setupUi(self)
        self.ui.pushButton.clicked.connect(self.doLogin)

    def doLogin(self):
        self.password = unicode(self.ui.password.text())
        self.email = unicode(self.ui.email.text())      
        request_data = {"username": ""+self.email+"", "password": ""+self.password+""}
        response = doLogin(request_data)

        if response.status_code == 200:
            """ 
                1. Save Api token for future entries
                2. Start app. i.e create a system tray app.
            """
            self.token = response.json()['token'];

            self.hide()
            trayIcon = SystemTrayIcon(QtGui.QIcon("Bomb.xpm"))
            trayIcon.show()
            print "End check"
        else:
            #Raise error
            print response.json()

3. Main File

import sys
from PyQt4 import QtGui, QtCore
from modules.login import Login

def main():
    app = QtGui.QApplication(sys.argv)
    login = Login()
    login.show()
    sys.exit(app.exec_())


if __name__ == "__main__":
    main()   

PROBLEM - System tray icon is not showing up when login dialog close.

Your input is highly appreciated.

도움이 되었습니까?

해결책

The trayIcon object is a local variable and immediately gets garbage collected once the doLogin() method finishes. Storing it as an instance attribute (eg self.trayIcon) will stop that and your icon should stay in existence.

다른 팁

QSystemTrayIcon has an activated signal that you can emit. Connect this signal to some method that will create a QMenu.

class SystemTrayIcon(QtGui.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        ...
        self.setContextMenu(menu)
        self.activated.connect(lambda reason: self._create_menu)

    def _create_menu(self):
        menu = QtWidgets.QMenu()
        menu.addAction(QtWidgets.QAction('Quit,None))
        self.setContextMenu(menu)

Next you'll want to emit the activated signal so that your menu will show. I had a similar use case that's answered here.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top