Qt: Làm cách nào để xử lý trường hợp người dùng nhấn nút 'X' (đóng)?


126

Tôi đang phát triển một ứng dụng bằng Qt. Tôi không biết vị trí nào tương ứng với sự kiện "người dùng nhấp vào nút 'X' (đóng) của khung cửa sổ" tức là nút này:

Nút đóng cửa sổ

Nếu không có chỗ cho việc này, có ai có thể gợi ý cho tôi một số phương pháp khác mà tôi có thể bắt đầu một chức năng sau khi người dùng nhấn nút đóng đó không.

Câu trả lời:


169

Nếu bạn có, QMainWindowbạn có thể ghi đè closeEventphương thức.

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


Nếu bạn đang phân lớp a QDialog, closeEventsẽ không được gọi và do đó bạn phải ghi đè 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();
    }
}

Nếu ứng dụng của tôi được tạo bằng cách phân lớp con QApplication, thì làm cách nào để đạt được điều tương tự như trên?
prakashpun

@ pra16 connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));sẽ hoạt động. Hãy xem câu trả lời của Sebastian bên dưới.
Shiva

1
Bạn cũng có thể muốn sử dụng setAttribute(Qt::WA_QuitOnClose);cho MainWindow.
Borzh

Bạn có chắc chắn rằng lớp con QDialog sẽ không gọi closeEvent? Nó hoạt động với tôi và tài liệu của QCloseEvent nói rằng Trình xử lý sự kiện QWidget :: closeEvent () nhận các sự kiện gần và QDialog cũng là một Widget đúng không? Hay nó có liên quan đến phiên bản Qt cũ hơn (<5.x) bằng cách nào đó?
Dimitri Podborski,

1
@incBrain Ngay cả trong Qt 4.8, nút 'X' gọi closeEventtrong QDialog, nhưng nếu người dùng nhấn Esc trên bàn phím, QDialog sẽ đóng mà không gọi closeEvent.
asclepix,

16

Tôi hiểu rồi. Một cách là ghi đè phương thức trong định nghĩa lớp của bạn và thêm mã của bạn vào hàm đó. Thí dụ: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

Bạn có thể đính kèm SLOT vào

void aboutToQuit();

tín hiệu về QApplication của bạn. Tín hiệu này sẽ được nâng lên ngay trước khi ứng dụng đóng.


2
Chúng tôi sử dụng nó loại:connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));
Sebastian Lange

3
Tuy nhiên, trích dẫn từ tài liệu : "Lưu ý rằng không thể tương tác với người dùng ở trạng thái này."
Ignitor

10

Ngoài ra, bạn có thể thực hiện lại thành viên được bảo vệ QWidget :: closeEvent ()

void YourWidgetWithXButton::closeEvent(QCloseEvent *event)
{
    // do what you need here
    // then call parent's procedure
    QWidget::closeEvent(event);
}
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.