Pregunta

Cuando se ejecuta el siguiente código, la aplicación de la bandeja puede aparecer en el objeto Heralwindow Qlabel en el medio de la pantalla. Pero al cerrar esta pantalla, toda la aplicación se apaga sin errores (el icono de la bandeja desaparece y el registro de la consola no muestra ningún error).

import sys
from PyQt4 import QtGui, QtCore


class AboutWindow(QtGui.QLabel):

def __init__(self, parent=None):
    QtGui.QLabel.__init__(self, parent=parent)
    self.setText("""
    Huge text goes here
    """)


class SystemTrayIcon(QtGui.QSystemTrayIcon):
    def __init__(self, icon, parent=None):
        QtGui.QSystemTrayIcon.__init__(self, icon, parent)
        menu = QtGui.QMenu(parent)
        self.createMenuActions(menu)
        self.setContextMenu(menu)
        # I've tried using the same parent as QSystemTrayIcon, 
        # but the label is not shown.
        # self.aboutWindow = AboutWindow(parent=parent)
        self.aboutWindow = AboutWindow(parent=None)


    def createMenuActions(self, menu):
        exitAction = QtGui.QAction("Exit", menu)
        configureAppAction = QtGui.QAction("Configure Application", menu)
        aboutAction = QtGui.QAction("About", menu)

        self.connect(configureAppAction, QtCore.SIGNAL('triggered()'), self._configureApp)
        self.connect(aboutAction, QtCore.SIGNAL('triggered()'), self._showAbout)
        self.connect(exitAction, QtCore.SIGNAL('triggered()'), self._exitApp)

        self.addActionsToMenu(menu, configureAppAction, aboutAction, exitAction)

    def addActionsToMenu(self, menu, *args):
        for action in args:
            menu.addAction(action)

    def _configureApp(self): pass

    def _showAbout(self):
        self.aboutWindow.show()

    def _exitApp(self):
        sys.exit(0)

def main():
    app = QtGui.QApplication(sys.argv)
    widget = QtGui.QWidget()
    # I'm passing a widget parent to QSystemTrayIcon as pointed out in:
    # http://stackoverflow.com/questions/893984/pyqt-show-menu-in-a-system-tray-application
    trayIcon = SystemTrayIcon(QtGui.QIcon("icon.xpm"), widget)
    trayIcon.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

Como se señaló en el código, he intentado configurar el mismo padre para el icono de la bandeja y el objeto HerterWindow, pero eso no funcionó (la etiqueta no se muestra). También he intentado subclasificar QMainWindow, pero ocurrió el mismo efecto.

Me gustaría entender si ese es el comportamiento predeterminado al abrir una nueva ventana de Qsystemtrayicon cuando ni la ventana y el ícono comparten el mismo padre, y si hay una solución para este asunto.

Gracias.

¿Fue útil?

Solución

Muy bien, supongo que no tenía demasiado claro el problema, pero encontré una solución simple.

QT tiene un método que captura el evento cercano enviado a un widget (http://doc.qt.nokia.com/4.6/qwidget.html#closeevent). Puede, en su subclase QWidget, reescribir este método para evitar que el widget se cierre (lo que, en todas mis pruebas, cerraría toda la aplicación) y solo lo ocultaría. El siguiente código muestra lo que he cambiado en mi código para que funcione:

...

class AboutWindow(QtGui.QLabel):

    def __init__(self, parent=None):
        QtGui.QLabel.__init__(self, parent=parent)
        self.setText("""
        Huge text goes here
        """)

    # Prevent the widget from closing the whole application, only hides it
    def closeEvent(self, event):
        event.ignore()
        self.hide()

...

Otros consejos

Este problema ocurre porque cuando cierra la ventana 'Solo', QT cree erróneamente que desea renunciar a la aplicación. Tu respuesta (Kaos12) es una solución fea en mi humilde opinión, a veces realmente quieres cerrar las cosas (que no es lo mismo que ocultarlo). La forma correcta de hacerlo es deshabilitar este comportamiento agregando la línea:

app.setQuitOnLastWindowClosed(False)

Después de la línea 50 en ese código (después de 'crear' la aplicación). Esta instrucción le dirá a QT que no renuncie a la aplicación incluso cuando todas las ventanas estén cerradas.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top