2010-09-01 9 views
1

Voici le code de mon application de bac simple. Il se bloque avec segfault lorsque j'appelle la fenêtre d'information du menu contextuel de l'application et la ferme ensuite. J'ai essayé différentes variantes pour trouver une raison de segfault, c'est mon dernier essai.L'application PyQt se bloque après la fermeture de la fenêtre QMessagebox

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import sys 
from PyQt4 import QtCore 
from PyQt4 import QtGui  

class SystemTrayIcon(QtGui.QSystemTrayIcon): 
    def __init__(self, parent=None): 
     QtGui.QSystemTrayIcon.__init__(self, parent) 

     self.setIcon(QtGui.QIcon("icon.png")) 

     self.iconMenu = QtGui.QMenu(parent) 
     appabout = self.iconMenu.addAction("About") 
     appexit = self.iconMenu.addAction("Exit") 
     self.setContextMenu(self.iconMenu) 

     self.aboutdialog = QtGui.QWidget(parent) 

     self.connect(appabout,QtCore.SIGNAL('triggered()'),self.showAbout) 
     self.connect(appexit,QtCore.SIGNAL('triggered()'),self.appExit) 

     self.show() 


    def showAbout(self): 
     QtGui.QMessageBox.information(self.aboutdialog, self.tr("About Tunarium"), self.tr("Your text here.")) 

    def appExit(self): 
     sys.exit() 


if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 

    trayIcon = SystemTrayIcon() 
    trayIcon.show() 

    sys.exit(app.exec_()) 

Répondre

3

Je ne sais pas Python, mais dans votre appExit(), vous devrait appeler quit() ou exit() sur l'objet de l'application qui fera appel à votre sys.exit(app.exec_()) en principal pour revenir. Encore une fois, ne connaissant pas les spécificités de Python, vous pouvez le faire en utilisant la macro Qt qApp et appelez qApp->quit() ou QCoreApplication::instance()->quit(). L'appel quit() est identique à l'appel exit(0). Vous pouvez utiliser exit() directement pour renvoyer le code de sortie de votre choix.

Mise à jour: J'ai essayé votre code en C++ avec quelques réglages et cela fonctionne. J'ai commenté où vous devriez essayer d'apporter des modifications à votre code. J'espère que ça marche pour toi.

#!/usr/bin/env python 
# -*- coding: utf-8 -*- 

import sys 
from PyQt4 import QtCore 
from PyQt4 import QtGui  

class SystemTrayIcon(QtGui.QSystemTrayIcon): 
    def __init__(self, parent=None): 
     QtGui.QSystemTrayIcon.__init__(self, parent) 

     self.setIcon(QtGui.QIcon("icon.png")) 

     self.iconMenu = QtGui.QMenu(parent) 
     appabout = self.iconMenu.addAction("About") 
     appexit = self.iconMenu.addAction("Exit") 
     self.setContextMenu(self.iconMenu) 

     # Remove this next line, it isn't needed 
     #self.aboutdialog = QtGui.QWidget(parent) 

     self.connect(appabout,QtCore.SIGNAL('triggered()'),self.showAbout) 
     self.connect(appexit,QtCore.SIGNAL('triggered()'),self.appExit) 

     # Remove this next line, it isn't needed 
     #self.show() 


    def showAbout(self): 
     # Before showing the message box, disable the tray icon menu 
     self.iconMenu.setEnabled(false) 
     # Replace self.aboutdialog with the Python equivalent of null (0?) 
     QtGui.QMessageBox.information(0, self.tr("About Tunarium"), self.tr("Your text here.")) 
     # Re-enable the tray icon menu 
     self.iconMenu.setEnabled(true) 

    def appExit(self): 
     # Replace the next line with something that calls the QApplication's 
     # exit() or quit() function. 
     #sys.exit() 
     app.quit() 


if __name__ == "__main__": 
    app = QtGui.QApplication(sys.argv) 
    # Tell the application not to exit when the last window is closed. This should 
    # prevent the application from exiting when the message box is closed. 
    app.setQuitOnLastWindowClosed(false) 

    trayIcon = SystemTrayIcon() 
    trayIcon.show() 

    sys.exit(app.exec_()) 

Mise à jour 2:

Comme demandé, voici l'équivalent du code C++:

main.cpp

#include <QtGui/QApplication> 

#include "SystemTrayIcon.h" 

int main(int argc, char *argv[]) 
{ 
    QApplication app(argc, argv); 
    app.setQuitOnLastWindowClosed(false); 
    SystemTrayIcon trayIcon(&app); 
    trayIcon.show(); 

    return app.exec(); 
} 

SystemTrayIcon.h

#ifndef SYSTEMTRAYICON_H 
#define SYSTEMTRAYICON_H 

#include <QtGui/QSystemTrayIcon> 
#include <QtGui/QAction> 
#include <QtGui/QMenu> 
#include <QtGui/QWidget> 

class SystemTrayIcon : public QSystemTrayIcon 
{ 
    Q_OBJECT 

public: 
    SystemTrayIcon(QObject * parent = 0); 
    virtual ~SystemTrayIcon(); 

private: 
    QAction * m_appabout; 
    QAction * m_appexit; 
    QMenu * m_iconMenu; 
    QWidget * m_aboutdialog; 

private slots: 
    void slot_showAbout(); 
    void slot_exit(); 
}; 

#endif /* SYSTEMTRAYICON_H */ 

SystemTrayIcon.cpp

#include <iostream> 
#include <QtCore/QCoreApplication> 
#include <QtGui/QIcon> 
#include <QtGui/QAction> 
#include <QtGui/QMessageBox> 

#include "SystemTrayIcon.h" 

SystemTrayIcon::SystemTrayIcon(QObject * parent) : 
    QSystemTrayIcon(parent), 
    m_appabout(0), 
    m_appexit(0), 
    m_iconMenu(0), 
    m_aboutdialog(0) 
{ 
    setIcon(QIcon("icon.png")); 

    m_iconMenu = new QMenu(); 
    m_appabout = m_iconMenu->addAction("About"); 
    m_appexit = m_iconMenu->addAction("Exit"); 
    setContextMenu(m_iconMenu); 

    connect(m_appabout, SIGNAL(triggered()), this, SLOT(slot_showAbout())); 
    connect(m_appexit, SIGNAL(triggered()), this, SLOT(slot_exit())); 
} 

SystemTrayIcon::~SystemTrayIcon() 
{ 
} 

void SystemTrayIcon::slot_showAbout() 
{ 
    std::cout << "slot show about." << std::endl; 
    m_iconMenu->setEnabled(false); 
    QMessageBox::information(0, "About Tunarium", "Your text here."); 
    m_iconMenu->setEnabled(true); 
} 

void SystemTrayIcon::slot_exit() 
{ 
    std::cout << "slot exit." << std::endl; 
    qApp->quit(); 
} 
+0

Si j'utilise la sortie my application se bloque avec segfault. Je vais jouer avec, mais maintenant tout fonctionne bien. – PocketSam

+0

Je vais jeter un autre coup d'oeil ce soir. Il y a quelque chose d'un peu inhabituel dans la façon dont vous créez un widget pour aboutdialog, puis créez une boîte de message et parlez-en au widget aboutdialog. Vous appelez aussi show() dans l'init, ce qui peut poser problème. –

+0

J'ai mis à jour ma réponse avec quelques suggestions de code. J'espère que cela aide. –

Questions connexes