0

Good day. Dealing with QMouseEvent. Made a project with its own class, which implements a player based on 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

and implementation

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

Then objects of this class are pushed onto my QGraphicsScene implementation

#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()
{
    
}

Graphics scene in a single window

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

I am trying to achieve that when these widgets, playing gifs on QGraphicsScene, can be clicked with the mouse and get some kind of reaction. However, clicking the mouse buttons does nothing. It's not clear why, like everything is according to the textbook.

Anton1978
  • 35
  • 7

1 Answers1

0
  1. The mouse event is not delivered to your widget, it's delivered to the label. To peek into the events the label receives, implement the filterEvent method in your widget, and install that widget as the event filter for the label.

  2. When overriding methods, always add the override specifier - that way you'll be sure that you're using the correct signature of the method. If your code won't compile, this tells you that you're not overriding anything but adding a new method with a signature perhaps slightly different from what it should be. Such mistakes are easy to make, and in large code bases they are silent errors that may lay dormant for years if there's insufficient test coverage (not unusual) - that's why the override specifier was added to C++.

Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313