Hauptfenster schließt durch magische Hand



  • Hallo,

    Ich habe einen bösen Bug.

    Ich habe vor einiger Zeit mal eine Todo-Liste programmiert, dessen Hauptfenster man auch verstecken kann. Wenn das Fenster versteckt ist und ein Alarm ausgelöst wird, schließt sich das Hauptfenster und das Programm beendet (und das soll es nicht). Kein Segmentation Fault oder derartiges, das Programm geht einfach zu Ende. Wenn das Hauptfenster jedoch nicht versteckt ist und ein Alarm ausgelöst wird, bleibt das Fenster offen. Der Debugger hilft mir irgendwie nicht viel weiter, ich halte bei der Methode show_message() und danach springt er in irgendwelche Qt-Dateien, schlussendlich in die main() -Funktion in die letzte Zeile ( return program.exec(); ) und dann beendet das Programm. Echt gar keinen Plan warum.

    Ich zeige mal ein bisschen Code, vielleicht erkennt ja jemand wo mein Fehler liegen könnte:

    /// hier wird der Alarm ausgelöst
    void alarm::show_message(){
        std::unique_ptr<sdl::music> sound;
    
        if(QFile::exists(info.sound_file_path)){
            sound.reset(new sdl::music(info.sound_file_path.toStdString()));
            sound->play();
        }
    
        environment::notify(info.title.toStdString(), info.message.toStdString());
        QMessageBox::information(nullptr, info.title, info.message);
    
        ((QWidget*)parent())->parentWidget()->show(); // diese Zeile löst das Problem. Das Ding ist nur, es soll weiter versteckt bleiben.
    }
    

    Und so sieht meine main() -Funktion aus:

    #include <QApplication>
    #include "main_window.hpp"
    
    int main(int argc, char** argv){
        QApplication tobedone{argc, argv};
    
        main_window* window = new main_window;
        window->setAttribute(Qt::WA_DeleteOnClose);
        window->setFixedSize(700, 400);
    
        if(argc > 1 && (std::string{argv[1]} == "--hide" || std::string{argv[1]} == "-h"))
            window->hide();
        else
            window->show();
    
        return tobedone.exec();
    }
    

    Ich habe das Programm bei show_message() angehalten und bin bis zum Ende durchgedebugget. So sieht der Callstack aus:

    1 ??                                                                                     0x7ffff529ca41 
    2 g_main_context_dispatch                                                                0x7ffff1ddbe67 
    3 ??                                                                                     0x7ffff1ddc0d0 
    4 g_main_context_iteration                                                               0x7ffff1ddc17c 
    5 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)             0x7ffff529d57f 
    6 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)                                0x7ffff52470da 
    7 QCoreApplication::exec()                                                               0x7ffff524f5cc 
    8 main                                                                       main.cpp 19 0x40c5a8
    

    Ich kann da irgendwie nix vernünftiges rauslesen.

    Ich bitte um Rat.



  • Ich kenne mich weder mit Qt noch mit Cpp aus, aber gib mal QMessageBox::information sein Parent als erstes Argument mit.



  • Same result here.

    Es liegt auch nicht am Qt::WA_DeleteOnClose . Ich habe das Hauptfenster zur Abwechselung mal auf den Stack gelegt, immer noch das gleiche Resultat.



  • Die Qt Application beendet sich normalerweise, wenn das letzte Fenster geschlossen wird. Ich bin mir nicht ganz sicher, wie es sich mit versteckten Widgets verhält. Hab mal kurz in den Code geschaut (qwidget.cpp), sieht tatsächlich so aus, als ob versteckte QWidgets nicht zählen. D.h., das würde dein Verhalten erklären.
    Schau dir mal die quitOnLastWindowClosed an. Wenn du das auf false setzt, musst du dich allerdings selber mal darum kümmern, die QApplication zu beenden.



  • Wow, super, danke!

    Darauf wäre ich zur Abwechselung mal nicht selber darauf gekommen.

    Ich mache setQuitOnLastWindowClosed(false) , dann überschreibe ich die closeEvent() des Hauptfensters, wenn das Fenster dann tatsächlich geschlossen werden soll, mach ich QApplication::exit(0) . Voilà.



  • lonely schrieb:

    Darauf wäre ich zur Abwechselung mal nicht selber darauf gekommen.

    Sowas findet man schon raus. Du musst dich halt dran gewöhnen, den Qt Code selber zu verstehen und da reinzudebuggen. Je intensiver man das benutzt, desto wahrscheinlicher ist es, dass man da reindebuggen muss oder sogar selber was ändern.


Anmelden zum Antworten