c++ - 如何在子小部件下使用eventfilter来捕获自定义事件

标签 c++ qt user-interface events qt5

最近,我需要用一个自定义的事件类型MyEvent替换Pong Gui的按键事件类型(以使用UDP信号代替<-->来控制游戏)。但是问题是似乎对于自定义事件我需要手动发送或发布它们,而事件过滤器无法接收自定义事件(内置的按键或鼠标单击似乎不需要手动发送)。事件过滤器的安装方式与mainwindow.cpp中相同:ui-> boardView-> installEventFilter(gameloop iLoop);
eventfilter在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;
}

'''

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

mainwindow.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
谢谢通用!
问题是,当我们尝试发布到ui-> boardView时,它报告“未声明的标识符”,因为ui-> boardview不在main.cpp中定义,而是在mainwindow.cpp中定义

最佳答案

显示的代码有一些基本问题。首先,如果您想让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);
}

其次,一旦处理了一个事件,它将由Qt事件处理代码delete d进行处理,因此通常来说,您必须在堆上分配事件。因此,上面的代码将导致在无效的内存位置上调用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);
}

关于c++ - 如何在子小部件下使用eventfilter来捕获自定义事件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60424216/

相关文章:

java - JTextArea 的属性如何由事件更新?

c++ - 使用 CUDA 7.0/VS2012 C++/CLI/OpenCV 的多线程 CPU 到 GPU

qt - QwtPlot - 多个 Y 轴

c++ - 是否可以使用 QMaemo5ListPickSelector 将图像显示为项目?

c++ - 递归遍历 Qt 中目录及其子目录中的所有文件

c++ - 如何使用gdb调试GUI程序

c++ - 单击按钮时QT在另一个矩形之上绘制一个矩形

c++ - 使用 C++ 在文件中进行字符串搜索/索引

c++ - 关于一个编译器同时执行多个任务

c++ - cuda推力中的fp16支持