Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to capture the QDockWidget close button click event

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.

like image 310
paulm Avatar asked Feb 14 '13 09:02

paulm


2 Answers

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);
like image 133
Jens A. Koch Avatar answered Nov 16 '22 06:11

Jens A. Koch


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.

like image 32
paulm Avatar answered Nov 16 '22 07:11

paulm