Как использовать EventFilter под дочерним виджетом, чтобы поймать событие самоопределения - PullRequest
2 голосов
/ 27 февраля 2020

В последнее время мне нужно заменить тип события нажатия клавиши Понг Gui на определенный пользователем тип события MyEvent (вместо этого использовать UDP-сигнал <- -> для управления игрой). Однако проблема в том, что кажется, что для самоопределяемого события мне нужно вручную отправить или опубликовать их, в то время как фильтр событий не может получить самоопределяемое событие (встроенное нажатие клавиши или щелчок мышью, похоже, не требуют ручной отправки). Фильтр событий был установлен как в главном окне. cpp: ui-> boardView-> installEventFilter (gamel oop iL oop); EventFilter реализован в игровом процессе. 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;
}

' ''

Основной. 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();
}
'''

главное окно. cpp - это

'''
//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);
}

'' '

Так как я могу передать свое самоопределенное событие в фильтр событий GUI?

Спасибо! ----------------------------------- 200227 Спасибо GM! Проблема в том, что когда мы пытаемся выполнить публикацию в ui-> boardView, он сообщает «необъявленный идентификатор», поскольку ui-> boardview определяется не в main. cpp, а в mainwindow. cpp

1 Ответ

1 голос
/ 27 февраля 2020

Показанный код имеет несколько основных проблем c. Во-первых, если вы хотите, чтобы ui->boardView принимал события, вам следует отправить события на ui->boardView: не на экземпляр MainWindow, как вы это сделали в ...

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);
}

Во-вторых, один раз событие было обработано, оно будет delete d кодом обработки событий Qt, так что, вообще говоря, вы должны выделить события в куче. Таким образом, приведенный выше код приведет к вызову delete в недопустимых местах памяти и, следовательно, к неопределенному поведению. Это должно быть изменено на ...

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);
}
...