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.