0

再会。处理 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 时,可以用鼠标单击并获得某种反应。但是,单击鼠标按钮没有任何作用。不清楚为什么,就像一切都根据教科书。

4

1 回答 1

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

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

于 2020-12-28T16:54:23.133 回答