Qt: Comment gérer l'événement de l'utilisateur appuyant sur le bouton «X» (fermer)?


126

Je développe une application utilisant Qt. Je ne sais pas quel slot correspond à l'événement "l'utilisateur clique sur le bouton 'X' (fermer) du cadre de la fenêtre" c'est à dire ce bouton:

Bouton de fermeture de la fenêtre

S'il n'y a pas de slot pour cela, quelqu'un peut-il me suggérer une autre méthode par laquelle je peux démarrer une fonction après que l'utilisateur a appuyé sur ce bouton de fermeture.

Réponses:


169

Si vous avez une méthode, QMainWindowvous pouvez remplacer closeEvent.

#include <QCloseEvent>
void MainWindow::closeEvent (QCloseEvent *event)
{
    QMessageBox::StandardButton resBtn = QMessageBox::question( this, APP_NAME,
                                                                tr("Are you sure?\n"),
                                                                QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
                                                                QMessageBox::Yes);
    if (resBtn != QMessageBox::Yes) {
        event->ignore();
    } else {
        event->accept();
    }
}


Si vous sous-classez a QDialog, le closeEventne sera pas appelé et vous devez donc remplacer reject():

void MyDialog::reject()
{
    QMessageBox::StandardButton resBtn = QMessageBox::Yes;
    if (changes) {
        resBtn = QMessageBox::question( this, APP_NAME,
                                        tr("Are you sure?\n"),
                                        QMessageBox::Cancel | QMessageBox::No | QMessageBox::Yes,
                                        QMessageBox::Yes);
    }
    if (resBtn == QMessageBox::Yes) {
        QDialog::reject();
    }
}

Si mon application est créée en sous-classant QApplication, comment puis-je réaliser la même chose que ci-dessus?
prakashpun

@ pra16 connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));devrait fonctionner. Voir la réponse de Sebastian ci-dessous.
Shiva

1
Vous pouvez également utiliser setAttribute(Qt::WA_QuitOnClose);pour MainWindow.
Borzh

Êtes-vous sûr que la sous-classification de QDialog n'appellera pas closeEvent? Cela fonctionne pour moi, et la documentation de QCloseEvent dit que le gestionnaire d'événements QWidget :: closeEvent () reçoit des événements de fermeture et QDialog est également un widget, non? Ou est-ce lié à l'ancienne version de Qt (<5.x) d'une manière ou d'une autre?
Dimitri Podbourski

1
@incBrain Même dans Qt 4.8, le bouton 'X' appelle closeEventun QDialog, mais si l'utilisateur appuie sur Echap sur le clavier, le QDialog se ferme sans appeler closeEvent.
asclepix

16

Eh bien, je l'ai. Une façon est de remplacer la méthode dans votre définition de classe et d'ajouter votre code dans cette fonction. Exemple:QWidget::closeEvent(QCloseEvent *event)

class foo : public QMainWindow
{
    Q_OBJECT
private:
    void closeEvent(QCloseEvent *bar);
    // ...
};


void foo::closeEvent(QCloseEvent *bar)
{
    // Do something
    bar->accept();
}

12

Vous pouvez attacher un SLOT au

void aboutToQuit();

signal de votre QApplication. Ce signal doit être émis juste avant la fermeture de l'application.


2
Nous l'avons utilisé en quelque sorte:connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));
Sebastian Lange

3
Cependant, citez la documentation : "Notez qu'aucune interaction utilisateur n'est possible dans cet état."
Ignitor

10

vous pouvez également réimplémenter le membre protégé QWidget :: closeEvent ()

void YourWidgetWithXButton::closeEvent(QCloseEvent *event)
{
    // do what you need here
    // then call parent's procedure
    QWidget::closeEvent(event);
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.