ถาม: ฉันจะจัดการกับเหตุการณ์ที่ผู้ใช้กดปุ่ม 'X' (ปิด) ได้อย่างไร?


126

ฉันกำลังพัฒนาแอปพลิเคชันโดยใช้ Qt ฉันไม่ทราบว่าช่องใดที่สอดคล้องกับเหตุการณ์ของ "ผู้ใช้คลิกปุ่ม 'X' (ปิด) ของกรอบหน้าต่าง" นั่นคือปุ่มนี้:

ปุ่มปิดของหน้าต่าง

หากไม่มีช่องนี้ใครช่วยแนะนำวิธีการอื่นให้ฉันด้วยซึ่งฉันสามารถเริ่มฟังก์ชันได้หลังจากที่ผู้ใช้กดปุ่มปิดนั้น

คำตอบ:


169

หากคุณมีQMainWindowคุณสามารถแทนที่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();
    }
}


หากคุณกำลัง subclassing QDialogที่closeEventจะไม่ถูกเรียกและดังนั้นคุณต้องแทนที่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();
    }
}

หากแอปพลิเคชันของฉันถูกสร้างโดยคลาสย่อย QApplication ฉันจะทำสิ่งเดียวกันกับข้างบนได้อย่างไร
prakashpun

@ pra16 น่าconnect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));ทำงาน. ดูคำตอบของ Sebastian ด้านล่าง
พระอิศวร

1
คุณอาจต้องการใช้setAttribute(Qt::WA_QuitOnClose);สำหรับ MainWindow
Borzh

แน่ใจหรือว่าคลาสย่อย QDialog จะไม่เรียกcloseEvent? มันได้ผลสำหรับฉันและเอกสารของQCloseEventบอกว่าตัวจัดการเหตุการณ์ QWidget :: closeEvent () ได้รับเหตุการณ์ที่ใกล้ชิดและ QDialog ก็เป็นวิดเจ็ตด้วยใช่ไหม หรือเกี่ยวข้องกับ Qt เวอร์ชันเก่ากว่า (<5.x) อย่างใด
Dimitri Podborski

1
@incBrain แม้ใน Qt 4.8 'X' ปุ่มโทรcloseEventใน QDialog แต่ถ้าผู้ใช้กดEscบนแป้นพิมพ์ QDialog closeEventถูกปิดโดยไม่ต้องโทร
asclepix

16

ฉันเข้าใจแล้ว วิธีหนึ่งคือการแทนที่เมธอดในนิยามคลาสของคุณและเพิ่มโค้ดของคุณลงในฟังก์ชันนั้น ตัวอย่าง: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

คุณสามารถแนบสล็อตเข้ากับไฟล์

void aboutToQuit();

สัญญาณของ QApplication ของคุณ สัญญาณนี้ควรขึ้นก่อนปิดแอป


2
เราใช้มันแบบ:connect(qApp,SIGNAL(aboutToQuit()),this,SLOT(quitMyApp()));
Sebastian Lange

3
อย่างไรก็ตามอ้างจากเอกสาร : "โปรดทราบว่าไม่มีการโต้ตอบกับผู้ใช้ในสถานะนี้"
Ignitor

10

นอกจากนี้คุณสามารถนำสมาชิกที่ได้รับการป้องกันมาใช้ใหม่ QWidget :: closeEvent ()

void YourWidgetWithXButton::closeEvent(QCloseEvent *event)
{
    // do what you need here
    // then call parent's procedure
    QWidget::closeEvent(event);
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.