Как реализовать mousePressEvent (событие QMouseEvent *) внутри класса?

Добрый день. Работа с QMouseEvent. Сделал проект со своим классом, реализующим плеер на основе QMovie.

#ifndef QTUBE_H
#define QTUBE_H
#include <QMovie>
#include <QLabel>
#include <QMouseEvent>
 
class QNewScene;
 
class QTube : public QWidget
{
    Q_OBJECT
public:
    QTube();
    QTube(QNewScene *scene, QString videourl, double x, double y, int speed);
    void qStop(); //остановка проигрывателя
    void qPlay(); //запуск проигрывателя
    void qToFrane(int frameNumber); //rewind video to the beginning
 
public slots:
    void qMovieEnd();
signals:
    void qTubeFinished();
 
private:
    QNewScene *newscene;
    QLabel *qlbl;
    QGraphicsProxyWidget* qvideoplayer;
    QTransform transformvideo;
    QMovie *qtopclip;
    int frame;  //frame number
    bool isOver; //truth when the video is over
    void mousePressEvent(QMouseEvent *event); //right mouse button to open the context menu
 
};
#endif // QTUBE_H

и реализация

#include "qtube.h"
#include "qnewscene.h"
#include <QGraphicsProxyWidget>
 
 
QTube::QTube()
{
}
QTube::QTube(QNewScene *scene, QString videourl, double x, double y, int speed): QWidget()
{
    isOver = false;
    newscene = scene;
    qlbl = new QLabel();
    qtopclip = new QMovie(videourl);
    qlbl->setAlignment(Qt::AlignTop | Qt::AlignLeft);
    qlbl->setContentsMargins(0,0,0,0);
    qlbl->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::MinimumExpanding);
    qvideoplayer = newscene->addWidget(qlbl);
    qvideoplayer->setPos(x,y);
    qlbl->setMovie(qtopclip);
    qtopclip->setSpeed(speed);
    qtopclip->start();
    qtopclip->stop();
    qlbl->setFixedHeight(qtopclip->currentImage().height());
    qlbl->setFixedWidth(qtopclip->currentImage().width());
    QObject::connect(qtopclip, &QMovie::finished, [ = ]() {this->qMovieEnd();});
}
 
void QTube::qStop()
{
    qtopclip->stop();
}
 
void QTube::qPlay()
{
    qtopclip->start();
}
 
void QTube::qToFrane(int frameNumber)
{
    qtopclip->jumpToFrame(frameNumber);
    qtopclip->stop();
}
 
void QTube::qMovieEnd()
{
    isOver = true;
    emit qTubeFinished();
    //qDebug() << qtopclip->fileName() << qtopclip->frameCount() << "  " << isOver;
}
 
void QTube::mousePressEvent(QMouseEvent *event)
{
    qDebug()<<"RIGHT BUTTON" << qtopclip->fileName();
    event->accept();
}

Затем объекты этого класса помещаются в мою реализацию QGraphicsScene.

#include "qnewscene.h"
#include "qglobalfon.h"
#include <QGraphicsProxyWidget>
 
QNewScene::QNewScene(QObject *parent) : QGraphicsScene(parent)
{
 
    //draw a global background, it's just a picture
    gf01 = new QGlobalFon (this);
 
    qTube01 = new QTube(this,":/new/prefix1/Items/Tube01.gif",137,666,500);
    qTube02 = new QTube(this,":/new/prefix1/Items/Tube02.gif",153,679,100);
    qTube03 = new QTube(this,":/new/prefix1/Items/Tube03.gif",140,666,500);
}
 
QNewScene::~QNewScene()
{
    
}

Графическая сцена в одном окне

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QMessageBox>
#include "qnewscene.h"
 
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    scene = new QNewScene(this);
    scene->setFont(QFont("Times", 13, 100, 0));
    scene->setSceneRect(0,0,1900,1200); // это чтобы сцена была ограничена окном
    ui->graphicsView->setScene(scene);
    ui->graphicsView->setBackgroundBrush(QBrush(QColor(115,204,207, 255), Qt::SolidPattern));
 
    //костыль чтобы все перерисовалось сразу как надо
    QSize newSize;
    newSize.setWidth(800);
    newSize.setHeight(600);
    QResizeEvent* resizeEvent = new QResizeEvent(newSize, ui->graphicsView->size());
    QCoreApplication::sendEvent(ui->graphicsView, resizeEvent);
 
}
 
MainWindow::~MainWindow()
{
    QMessageBox msgBox;
    msgBox.setText("Работа программы завершена");
    msgBox.exec();
    delete ui;
}

Я пытаюсь добиться того, чтобы эти виджеты, воспроизводящие гифки на QGraphicsScene, можно было щелкнуть мышью и получить какую-то реакцию. Однако нажатие кнопок мыши ничего не дает. Непонятно почему, вроде все по учебнику.


person Anton1978    schedule 28.12.2020    source источник


Ответы (1)


  1. Событие мыши не доставляется вашему виджету, оно доставляется на метку. Чтобы просматривать события, которые получает метка, реализуйте метод filterEvent в своем виджете и установите этот виджет в качестве фильтра событий для метки.

  2. При переопределении методов всегда добавляйте спецификатор override — таким образом вы будете убедитесь, что вы используете правильную подпись метода. Если ваш код не компилируется, это говорит о том, что вы ничего не переопределяете, а добавляете новый метод с сигнатурой, возможно, немного отличающейся от той, которая должна быть. Такие ошибки легко допустить, и в больших базах кода они являются скрытыми ошибками, которые могут бездействовать годами, если недостаточное тестовое покрытие (что не является чем-то необычным) — вот почему спецификатор override был добавлен в C++.

person Kuba hasn't forgotten Monica    schedule 28.12.2020