How to capture the QDockWidget close button click event

paulm picture paulm · Feb 14, 2013 · Viewed 7.5k times · Source

I have a QStackedWidget 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.

QDockWidget close button

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.

Answer

paulm picture paulm · Feb 14, 2013

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.