To capture the event of the close button being pressed without deriving from QWidget and the sort, you could use an event filter.
Here's a simple demonstration, using a simple application that displays a QWidget:
If you use QWidget itself, you need to capture QEvent::Close:
#include "myEventFilter.h"
#include <QApplication>
#include <QWidget>
int main(int argc,char*argv[])
{
    QApplication a(argc, argv);
    
    w.installEventFilter(filter);
    
    QWidget *w = new QWidget();
    //install the event filter on the widget
    w->installEventFilter(filter);
    w->show();
    return a.exec();
}
Event filter:
#ifndef MYEVENTFILTER_H
#define MYEVENTFILTER_H
#include <QObject>
#include <QDebug>
#include <QEvent>
class myEventFilter : public QObject
{
    Q_OBJECT
public:
    myEventFilter (QObject *parent = nullptr) {}
protected:
    bool eventFilter(QObject * obj, QEvent * event) override
    {
        if (event->type() == QEvent::Close)
        {
            //handle the event here
            qDebug()<<"out";
           //In case you need the QWidget itself 
           QWidget *w = static_cast<QWidget*>(obj);
        }
        return QObject::eventFilter(obj, event);
    }
};
#endif // MYEVENTFILTER_H
If you use QApplication's object, you need to capture  QEvent::Quit:
#include <QApplication>
#include "myEventFilter.h"
int main(int argc,char*argv[])
{
    QApplication a(argc, argv);
    QWidget *w = new QWidget();
    myEventFilter *filter = new myEventFilter();
    //install the event filter on QApplication object
    a.installEventFilter(filter);
    w->show();
    return a.exec();
}
Event filter
#ifndef MYEVENTFILTER_H
#define MYEVENTFILTER_H
#include <QObject>
#include <QDebug>
#include <QEvent>
#include <QLineEdit>
class myEventFilter : public QObject
{
    Q_OBJECT
public:
    myEventFilter (QObject *parent = nullptr) {}
protected:
    bool eventFilter(QObject * obj, QEvent * event) override
    {
        if (event->type() == QEvent::Quit)
        {
            //handle the event here as well
            qDebug()<<"out";
        }
        return QObject::eventFilter(obj, event);
    }
};
#endif // MYEVENTFILTER_H