I have a QStackedWidge
t within a QDockWidget
- depending on which page is shown I wish to show/hide the close button on the QDockWidget
. I can do this by using QDockWidget::setFeatures()
.
However the issue I'm facing is how to capture the signal of the close button so that I can change the dock features / set the stacked widget page index.
I have attempted to use an event filter:
class EventFilter : public QObject
{
Q_OBJECT
public:
EventFilter( QObject* aParent );
protected:
bool eventFilter(QObject *obj, QEvent *event);
};
EventFilter::EventFilter( QObject* aParent )
: QObject( aParent )
{
}
bool EventFilter::eventFilter( QObject *obj, QEvent *event )
{
if ( event->type() == QEvent::Close )
{
return true;
}
return QObject::eventFilter( obj, event );
}
And installed it as so:
EventFilter* filter = new EventFilter( this );
u->dockWidget_6->installEventFilter( filter );
In the constructor of my QMainWindow
- the eventFilter()
method did not get called.
So next I attempted to use the QDockWidget::visibilityChanged
changed signal since it sounded like this might be what I wanted:
connect( u->dockWidget_6, SIGNAL(visibilityChanged(bool)), SLOT(dockWindowClosed(bool)) );
This slot did get called - but not when the close button was clicked.
Finally I attempted to use a promoted QDockWidget
to capture the QWidget::closeEvent()
.
class DockWidgetWithCloseSignal : public QDockWidget
{
Q_OBJECT
public:
explicit DockWidgetWithCloseSignal(const QString &title, QWidget *parent = 0, Qt::WindowFlags flags = 0)
: QDockWidget( title, parent, flags )
{
}
explicit DockWidgetWithCloseSignal(QWidget *parent = 0, Qt::WindowFlags flags = 0)
: QDockWidget( parent, flags )
{
}
protected:
void closeEvent(QCloseEvent *event)
{
event->ignore();
}
};
I saw the constructor was called which means this new widget was indeed being used, but again no joy since the closeEvent()
was never called when the close button was clicked.
Create a new CloseDockWidget based on DockWidget.
Override the closeEvent() method, but emit an additional closed() signal from there.
widgets/qclosedockwidget.cpp:
#include "qclosedockwidget.h"
namespace Widgets
{
QCloseDockWidget::QCloseDockWidget(const QString &title, QWidget *parent)
: QDockWidget(title, parent)
{
// constructor
}
void QCloseDockWidget::closeEvent(QCloseEvent *event)
{
emit closed(); // <------ signal
QDockWidget::closeEvent(event);
}
} // namespace Widgets
widgets/qclosedockwidget.h:
#ifndef QCLOSEDOCKWIDGET_H
#define QCLOSEDOCKWIDGET_H
#include <QDockWidget>
namespace Widgets
{
class QCloseDockWidget : public QDockWidget
{
Q_OBJECT
public:
QCloseDockWidget(const QString &title = "", QWidget *parent = nullptr);
protected:
void closeEvent(QCloseEvent *event);
signals:
void closed();
};
} // namespace Widgets
#endif // QCLOSEDOCKWIDGET_H
Now you are able to instantiate and connect to the new signal:
auto *dockWidget = new Widgets::QCloseDockWidget("MyDockWidget", this);
connect(dockWidget, &Widgets::QCloseDockWidget::closed, this, &MainWindow::dockWidgetCloseClicked);
Turns out that everything apart from the visibilityChanged
signal works!
I added a signal to the overridden closeEvent()
method which I could then connect to any slot I wanted.
The actual issue was that within the stacked widget I had another QDockWidget
on another page, hence I was adding all of these things to the wrong QDockWidget
! (And of course promoted the wrong QDockWidget
too doh!).
Hopefully this question can serve as a reference to anyone else that needs to figure out how to do this - rather than why it isn't working.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With