Qt: Come gestisco l'evento in cui l'utente preme il pulsante "X" (chiudi)?


126

Sto sviluppando un'applicazione utilizzando Qt. Non so quale slot corrisponde all'evento "l'utente fa clic sul pulsante" X "(chiudi) del telaio della finestra", ovvero questo pulsante:

Pulsante Chiudi della finestra

Se non c'è uno slot per questo, qualcuno può suggerirmi qualche altro metodo con cui posso avviare una funzione dopo che l'utente ha premuto il pulsante di chiusura.

Risposte:


169

Se hai un metodo QMainWindowpuoi sovrascrivere 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();
    }
}


Se stai sottoclasse a QDialog, closeEventnon verrà chiamato e quindi devi sovrascrivere 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();
    }
}

Se la mia applicazione viene creata sottoclasse QApplication, come posso ottenere la stessa cosa di cui sopra?
prakashpun

@ pra16 connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));dovrebbe funzionare. Vedi la risposta di Sebastian di seguito.
Shiva

1
Potresti usarlo anche setAttribute(Qt::WA_QuitOnClose);per MainWindow.
Borzh

Sei sicuro che la sottoclasse QDialog non chiamerà closeEvent? Per me funziona, e la documentazione di QCloseEvent dice che Il gestore di eventi QWidget :: closeEvent () riceve eventi di chiusura e QDialog è anche un widget, giusto? O è in qualche modo correlato alla versione precedente di Qt (<5.x)?
Dimitri Podborski

1
@incBrain Anche in Qt 4.8 il pulsante "X" chiama closeEventin un QDialog, ma se l'utente preme Esc sulla tastiera, QDialog viene chiuso senza chiamare closeEvent.
asclepix

16

Bene, ho capito. Un modo è sovrascrivere il metodo nella definizione della classe e aggiungere il codice in quella funzione. Esempio: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

Puoi collegare uno SLOT al file

void aboutToQuit();

segnale della tua QApplication. Questo segnale dovrebbe essere generato appena prima della chiusura dell'app.


2
L'abbiamo usato come:connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));
Sebastian Lange

3
Tuttavia, cito dalla documentazione : "Notare che in questo stato non è possibile alcuna interazione con l'utente".
Ignitor

10

inoltre puoi reimplementare il membro protetto QWidget :: closeEvent ()

void YourWidgetWithXButton::closeEvent(QCloseEvent *event)
{
    // do what you need here
    // then call parent's procedure
    QWidget::closeEvent(event);
}
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.