如何在类中实现mousePressEvent(QMouseEvent * event)?

Posted

技术标签:

【中文标题】如何在类中实现mousePressEvent(QMouseEvent * event)?【英文标题】:How to implement mousePressEvent (QMouseEvent * event) inside a class? 【发布时间】:2020-12-28 14:53:13 【问题描述】:

美好的一天。 处理 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 上播放 gif,可以用鼠标单击并获得某种反应。但是,单击鼠标按钮没有任何作用。不清楚为什么,好像一切都按照教科书。

【问题讨论】:

【参考方案1】:

    鼠标事件不会传递给您的小部件,而是传递给标签。要查看标签接收的事件,请在您的小部件中实现 filterEvent 方法,并将该小部件安装为标签的事件过滤器。

    在覆盖方法时,请始终添加override specifier - 这样您就可以确保您使用的是正确的方法签名。如果您的代码无法编译,这表明您没有覆盖任何内容,而是添加了一个新方法,其签名可能与应有的略有不同。此类错误很容易犯,在大型代码库中,它们是无声错误,如果测试覆盖率不足(这并不罕见),它们可能会潜伏多年(这并不罕见)——这就是为什么将 override 说明符添加到 C++ 中的原因。

【讨论】:

以上是关于如何在类中实现mousePressEvent(QMouseEvent * event)?的主要内容,如果未能解决你的问题,请参考以下文章

如何在类中实现标准迭代器

mousePressEvent 没有正确绑定?

如何在类控制器中实现api swagger的spring注释?

覆盖 mousePressEvent 后 Qt Widget 调整大小

TypeScript 在类中实现接口

在类中实现委托(iOS/Swift)