2010-09-01 201 views
1

這是我的簡單托盤應用程序的代碼。當我從應用程序的上下文菜單中調用信息窗口並關閉它時,它會崩潰。 我試過不同的變體來找到段錯誤的原因,這是我的最後一次嘗試。關閉QMessagebox窗口後PyQt應用程序崩潰

#!/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_()) 

回答

3

我不知道Python的,但在你的appExit(),你應該調用應用程序對象,這將導致您的來電sys.exit(app.exec_())主返回上quit()exit()。再次,不知道Python的具體細節,你可以通過使用Qt宏qApp並調用qApp->quit()QCoreApplication::instance()->quit()來做到這一點。

調用quit()與調用exit(0)相同。您可以直接使用exit()返回您選擇的任何退出代碼。

更新: 我試過你的代碼在C++中進行了一些調整,它確實有效。我已經評論過你應該在哪裏嘗試對代碼進行更改。希望對你有效。

#!/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_()) 

更新2:

按照要求,這裏是等效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

如果我使用退出與段錯誤我的應用程序崩潰。我會玩,但現在一切正常。 – PocketSam 2010-09-07 06:14:43

+0

今天晚上我再看一次。對於創建aboutdialog組件的方式,然後創建一個消息框並將其父組件添加到aboutdialog組件,有一些不尋常的地方。你也在init中調用了show(),這可能是一個問題。 – 2010-09-07 12:50:00

+0

我已經用一些代碼建議更新了我的答案。希望能幫助到你。 – 2010-09-07 22:52:16