Reputation: 8067
Is there any way I can get notified when a user closes a QMdiSubWindow? I cannot find any signal in QMdiArea nor in QMdiSubWindow that suggests I can.
I think my only chance is by subclassing QMdiSubWindow and overriding the close event, but is there any other way?
Upvotes: 6
Views: 6345
Reputation: 1523
I had the same trouble, but in my case the task was more specific: "How to hide a subwindow when I press the close button instead of closing". So I solved this with the following:
subwindow->setAttribute(Qt::WA_DeleteOnClose, false);
Perhaps it's not a relevant answer but it may be useful for someone.
Upvotes: 2
Reputation: 2189
Yes, there is another way : you can install an event-filter on the QMdiSubWindow you create :
MdiSubWindowEventFilter * p_mdiSubWindowEventFilter;
...
QMdiSubWindow * subWindow = mdiArea->addSubWindow(pEmbeddedWidget);
subWindow->installEventFilter(p_mdiSubWindowEventFilter);
subWindow->setAttribute(Qt::WA_DeleteOnClose, true); // not mandatory, depends if you manage subWindows lifetime
with
bool MdiSubWindowEventFilter::eventFilter(QObject * obj, QEvent * e)
{
switch (e->type())
{
case QEvent::Close:
{
QMdiSubWindow * subWindow = dynamic_cast<QMdiSubWindow*>(obj);
Q_ASSERT (subWindow != NULL);
//
// do what you want here
//
break;
}
default:
qt_noop();
}
return QObject::eventFilter(obj, e);
}
Upvotes: 2
Reputation: 8994
You can create QWidget based class like:
class CloseWatcher : public QWidget
{
Q_OBJECT
private:
QString m_name;
signals:
void disposing( QString name );
public
CloseWatcher( QWidget * p )
: QWidget( p )
, m_name( p->objectName() )
{}
~CloseWatcher()
{
emit disposing( m_name );
}
};
and just use it:
// anywhere in code
QMdiSubWindow * wnd = getSomeWnd();
CloseWatcher * watcher = new CloseWatcher( wnd );
connect( watcher, SIGNAL( disposing( QString ) ), reveiver, SLOT( onDispose( QString ) ) );
Upvotes: 0
Reputation: 8067
Here is what I ended coding.
#ifndef __MYSUBWINDOW_H
#define __MYSUBWINDOW_H
#include <QMdiSubWindow>
#include <QCloseEvent>
#include <QDebug>
class MyQMdiSubWindow : public QMdiSubWindow
{
Q_OBJECT
signals:
void closed( const QString );
protected:
void closeEvent( QCloseEvent * closeEvent )
{
emit closed( this->objectName() );
closeEvent->accept();
}
};
#endif
Note that for my problem I need a way to identify which subwindow user is closing, and objectName does the work for me.
Upvotes: 0
Reputation: 4412
I don't think there is any other way than as you describe (overriding the close event) to do precisely what you're asking.
There might be other ways of achieving what you want without doing that depending on why you want to know when its closed. Other options could be the use of the destroyed signal, checking QApplication::focusWidget(), or perhaps having the parent inspect its children.
Edit in response to comment:
Signals and slots are disconnected automatically upon destruction of QObjects, and I would suggest looking at using QSharedPointers or QScopedPointers to handle your QObjects' lifespans instead. By applying these techniques, you shouldn't need a signal from a closed window.
Upvotes: 1