Ft: Wie gehe ich mit dem Ereignis um, bei dem der Benutzer die Taste 'X' (Schließen) drückt?

126

Ich entwickle eine Anwendung mit Qt. Ich weiß nicht, welcher Steckplatz dem Ereignis entspricht, dass "der Benutzer auf die Schaltfläche 'X' (Schließen) des Fensterrahmens klickt", dh diese Schaltfläche:

Schließen Sie die Schaltfläche des Fensters

Wenn es dafür keinen Steckplatz gibt, kann mir jemand eine andere Methode vorschlagen, mit der ich eine Funktion starten kann, nachdem der Benutzer diese Schaltfläche zum Schließen gedrückt hat.

Shiva
quelle

Antworten:

169

Wenn Sie eine haben QMainWindow, können Sie die closeEventMethode überschreiben .

#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();
    }
}


Wenn Sie eine Unterklasse a haben QDialog, closeEventwird die nicht aufgerufen und Sie müssen Folgendes überschreiben 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();
    }
}
Asclepix
quelle
Wenn meine Anwendung durch Unterklassen von QApplication erstellt wird, wie kann ich dann dasselbe wie oben erreichen?
Prakashpun
@ pra16 connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));sollte funktionieren. Siehe Sebastians Antwort unten.
Shiva
1
Möglicherweise möchten Sie auch setAttribute(Qt::WA_QuitOnClose);für MainWindow verwenden.
Borzh
Sind Sie sicher, dass die Unterklasse QDialog nicht aufgerufen wird closeEvent? Es funktioniert für mich und die Dokumentation von QCloseEvent besagt, dass der Ereignishandler QWidget :: closeEvent () nahe Ereignisse empfängt und QDialog auch ein Widget ist, oder? Oder hängt es irgendwie mit der älteren Qt-Version (<5.x) zusammen?
Dimitri Podborski
1
@incBrain Selbst in Qt 4.8 ruft die ' closeEventX' -Taste einen QDialog auf, aber wenn der Benutzer Esc auf der Tastatur drückt, wird der QDialog geschlossen, ohne aufzurufen closeEvent.
Asclepix
16

Nun, ich habe es verstanden. Eine Möglichkeit besteht darin, die Methode in Ihrer Klassendefinition zu überschreiben und Ihren Code in diese Funktion einzufügen. Beispiel:QWidget::closeEvent(QCloseEvent *event)

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


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

Sie können einen SLOT an die anhängen

void aboutToQuit();

Signal Ihrer QApplication. Dieses Signal sollte kurz vor dem Schließen der App ausgelöst werden.

Sebastian Lange
quelle
2
Wir haben es benutzt von:connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));
Sebastian Lange
3
Allerdings zitierte aus der Dokumentation : „Beachten Sie, dass keine Interaktion mit dem Benutzer in diesem Zustand möglich ist.“
Ignitor
10

Sie können auch das geschützte Mitglied QWidget :: closeEvent () erneut implementieren.

void YourWidgetWithXButton::closeEvent(QCloseEvent *event)
{
    // do what you need here
    // then call parent's procedure
    QWidget::closeEvent(event);
}
Alexander
quelle