Qt: Bagaimana cara saya menangani kejadian pengguna menekan tombol 'X' (tutup)?

126

Saya mengembangkan aplikasi menggunakan Qt. Saya tidak tahu slot mana yang berhubungan dengan peristiwa "pengguna mengklik tombol 'X' (tutup) dari bingkai jendela" yaitu tombol ini:

Tombol tutup jendela

Jika tidak ada slot untuk ini, adakah yang bisa menyarankan saya metode lain yang saya dapat memulai fungsi setelah pengguna menekan tombol tutup itu.

Siwa
sumber

Jawaban:

169

Jika Anda memiliki metode QMainWindowAnda dapat mengganti 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();
    }
}


Jika Anda membuat subclass a QDialog, closeEventtidak akan dipanggil sehingga Anda harus mengganti 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.dll
sumber
Jika aplikasi saya dibuat dengan subclassing QApplication, lalu bagaimana saya bisa mencapai hal yang sama seperti di atas?
prakashpun
@ pra16 connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));harus bekerja. Lihat jawaban Sebastian di bawah.
Shiva
1
Anda mungkin ingin juga menggunakan setAttribute(Qt::WA_QuitOnClose);untuk MainWindow.
Borzh
Apakah Anda yakin bahwa subclassing QDialog tidak akan memanggil closeEvent? Ini berfungsi untuk saya, dan dokumentasi QCloseEvent mengatakan bahwa pengendali peristiwa QWidget :: closeEvent () menerima peristiwa tertutup dan QDialog juga merupakan Widget, bukan? Atau apakah itu terkait dengan versi Qt yang lebih lama (<5.x) entah bagaimana?
Dimitri Podborski
1
@incBrain Bahkan di Qt 4.8 tombol 'X' memanggil closeEventdalam QDialog, tetapi jika pengguna menekan Esc pada keyboard, QDialog ditutup tanpa memanggil closeEvent.
asclepix
16

Baiklah, saya mengerti. Salah satu caranya adalah dengan mengganti metode dalam definisi kelas Anda dan menambahkan kode Anda ke dalam fungsi itu. Contoh:QWidget::closeEvent(QCloseEvent *event)

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


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

Anda dapat memasang SLOT ke

void aboutToQuit();

sinyal QApplication Anda. Sinyal ini harus dinaikkan tepat sebelum aplikasi ditutup.

Sebastian Lange
sumber
2
Kami menggunakannya seperti:connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));
Sebastian Lange
3
Namun, kutipan dari dokumentasi : "Perhatikan bahwa tidak ada interaksi pengguna yang dimungkinkan dalam keadaan ini."
Ignitor
10

Anda juga dapat menerapkan kembali anggota yang dilindungi QWidget :: closeEvent ()

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