I have two classes:
typedef std::shared_ptr<AdaptedWidget> window_ptr;
class WindowManager
{
public:
...
private:
std::stack<window_ptr> m_windowsStack;
}
and
class AdaptedWidget: public QWidget
{
Q_OBJECT
public:
AdaptedWidget(AdaptedWidget *parent = 0);
bool event(QEvent *event);
};
bool AdaptedWidget::event(QEvent *event)
{
if (event->type() == QEvent::NonClientAreaMouseButtonPress ||
event->type() == QEvent::MouseButtonPress)
{
qDebug() << "mainwindwo press";
}
return QWidget::event(event);
}
I need to get information about events that happen in AdaptedWidget
objects from my WindowManager
object, How can I do that?
Event filters are the Qt way to accomplish your task.
Make your WindowManager
class a subclass of QObject
and provide an implementation for its eventFilter()
method.
After that, every time you create an AdaptedWidget
use installEventFilter()
to install your WindowManager
instance as an event filter on it.
class WindowManager : public QObject
{
public:
...
bool eventFilter(QObject* obj, QEvent* ev);
private:
std::stack<window_ptr> m_windowsStack;
}
and
bool WindowManager::eventFilter(QObject* obj, QEvent* ev){
AdaptedWidget* widget= qobject_cast<AdaptedWidget*>(obj);
if(ev->type == /*type of event you are interested in*/){
//you can compare widget against the stack of widgets you have
//if you want to stop widget from receiving the event you can return true
}
return false;
}
and when creating each AdaptedWidget
instance, install the WindowManager
as an event filter:
AdaptedWidget* widget= new AdaptedWidget;
widget->installEventFilter(/*your WindowManager instance*/);
The AdaptedWidget
class should have a signal that indicates a mouse press, e.g.
class AdaptedWidget : ... {
Q_OBJECT
...
public:
Q_SIGNAL void mousePress(const QPoint &);
};
bool AdaptedWidget::event(QEvent *event)
{
if (event->type() == QEvent::NonClientAreaMouseButtonPress ||
event->type() == QEvent::MouseButtonPress)
{
auto ev = static_cast<QMouseEvent*>(event);
emit mousePress(ev->pos());
qDebug() << "mainwindow press";
}
return QWidget::event(event);
}
Another approach is to use event filters, but that unnecessarily tightly couples the two classes.