how to use eventfilter under child widget to catch self define event

Viewed 125

Recently I need to substitute the event type of keypress of a Pong Gui with a self defined event type MyEvent(to Use UDP signal instead <- -> to control the game). However the problem is that seems for self-defined event I need to manually send or post them, while the event filter can't receive the self-defined event (the inbuilt keypress or mouseclick seems need no manually send). The event filter was installed as in mainwindow.cpp: ui->boardView->installEventFilter(gameloop iLoop); the eventfilter is realized in gameplay.cpp: '''

bool Gameplay::eventFilter(QObject *target, QEvent *e)
{
    Q_UNUSED(target);

    bool handled = false;
    if(e->type() == MyEventType)
    {
        MyEvent *myevent = (MyEvent *)e;
        if ( myevent->sg >0)
        {
            //pong paddle move left
            iP1Direction = (iP1Direction == 0 ? -5 : 0);
            handled = true;
        }
        else if ( myevent->sg <0 )
        {
            //pong paddle move right
            iP1Direction  = (iP1Direction == 0 ? 5 : 0);
            handled = true;
        }
    }
    if(e->type() == MyEventType)
    {
        qDebug()<<"abc";
        handled = true;
    }
    return handled;
}

'''

The main.cpp '''

#include <QtWidgets/QApplication>
#include "mainwindow.h"
#include "MyEvent.h"
#include <iostream>
#include <cmath>
int main(int argc, char *argv[])
{

    QApplication a(argc, argv);

    MainWindow w;
    w.show();



    for(int i=0;i<1000;i++){
    MyEvent myEvent1(MyEventType);
    myEvent1.set_ch(1);
    myEvent1.load_sg(1);
    QCoreApplication::postEvent(&w, &myEvent1);
    }

    return a.exec();
}
'''

the mainwindow.cpp is

'''
//cited from https://github.com/ynonp/Pong
#include <QPen>
#include <QResizeEvent>
#include <QDebug>
#include <QtWidgets/QApplication>
#include "mainwindow.h"
#include "MyEvent.h"
#include <QCoreApplication>
#include <QEvent>
#include <QObject>
#include <QDebug>
#include <iostream>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    iScore ( 0 )
{
    ui->setupUi(this);

    QGraphicsScene *scene = new QGraphicsScene(this);

    QGraphicsRectItem *p1 = new QGraphicsRectItem(0, 0, 80, 20);
    p1->setBrush(QBrush(Qt::blue));
    QGraphicsRectItem *p2 = new QGraphicsRectItem(0, 0, 80, 20);
    p2->setBrush(QBrush(Qt::green));

    QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(0, 0, 15, 15);
    ball->setBrush(QBrush(Qt::magenta));

    ui->boardView->setScene(scene);

    iLoop = new Gameplay(*scene, p1, p2, ball, this);
    QSize m(scene->sceneRect().size().width() + 10, scene->sceneRect().size().height() + 10);
    ui->boardView->setMinimumSize(m);

    resize(minimumSize());
    ui->boardView->installEventFilter(iLoop);


    QObject::connect(iLoop, SIGNAL(goal(int)),
                     this, SLOT(addScore(int)));

}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::addScore(int count)
{
    iScore += count;
    ui->lcdNumber->display(iScore);
}

'''

So how can I feed my self defined event into the GUI event filter?

Thanks! -----------------------------------200227 Thanks GM! The problem is that when we trying to post to ui->boardView, it reports "undeclared identifier", as the ui->boardview is defined not in main.cpp but in mainwindow.cpp

1 Answers

The code shown has a few basic problems. Firstly, if you want ui->boardView to receive the events then you should sent the events to ui->boardView: not to the MainWindow instance as you have done in...

MainWindow w;
w.show();
for (int i = 0; i < 1000; i++) {
    MyEvent myEvent1(MyEventType);
    myEvent1.set_ch(1);
    myEvent1.load_sg(1);
    QCoreApplication::postEvent(&w, &myEvent1);
}

Secondly, once an event has been processed it will be deleted by the Qt event processing code so generally speaking you must allocate events on the heap. So the above code will result in delete being called on invalid memory locations and, hence, undefined behaviour. It should be changed to...

MainWindow w;
w.show();
for (int i = 0; i < 1000; i++) {
    auto *myEvent = new MyEvent1(MyEventType);
    myEvent1->set_ch(1);
    myEvent1->load_sg(1);
    QCoreApplication::postEvent(ui->boardView, myEvent1);
}
Related