2010-09-01 4 views
1

Вот код моего простого приложения для лотков. Он сбой с segfault, когда я вызываю информационное окно из контекстного меню приложения, а затем закрываю его. Я попробовал разные варианты, чтобы найти причину segfault, это моя последняя попытка.Сбой приложения PyQt после закрытия окна 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_()) 

ответ

3

Я не знаю, Python, но в вашем appExit(), вы должны называть quit() или exit() на объекте приложения, который будет вызывать ваш вызов sys.exit(app.exec_()) в основном, чтобы вернуться. Опять же, не зная специфики 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_()) 

Update 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

Если я использую выход мои сбои приложений с Segfault. Я буду играть с ним, но теперь все работает нормально. – PocketSam

+0

Я еще раз посмотрю сегодня вечером. Существует кое-что необычное в том, как вы создаете виджет для aboutdialog, а затем создаете окно сообщения и помещаете его в виджет aboutdialog. Вы также вызываете show() внутри init, что может быть проблемой. –

+0

Я обновил свой ответ с некоторыми предложениями кода. Надеюсь, поможет. –

Смежные вопросы