Learn about occurred events from other class

2019-07-30 18:14发布

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?

2条回答
Root(大扎)
2楼-- · 2019-07-30 18:57

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*/);
查看更多
太酷不给撩
3楼-- · 2019-07-30 19:05

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.

查看更多
登录 后发表回答