Qt视频播放窗口叠加透明窗口

Posted 秦时小

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt视频播放窗口叠加透明窗口相关的知识,希望对你有一定的参考价值。

前言

本人在做一个视频监控项目时,遇到了透明窗口无法透明的问题,特记录下解决过程。

更新:经测试,本文提到的方法用于多分屏复杂的视频播放窗口时有问题。


目录

前言

一、需求

二、关键代码

2.1、透明窗口设置

2.1.1、构造函数中调用以下代码

2.1.2、重载paintEvent事件

2.2、视频播放窗口设置

2.2.1、调用透明窗口

2.2.2、透明窗口位置及大小自适应视频窗口

2.2.3、坐标转换

 三、所有源码

3.1、透明窗口

3.2、视频播放窗口


一、需求

在视频播放界面上,叠加一个透明窗口,实现拉框局部放大功能。

本来以为这个很简单,直接给窗口加一个透明设置项就行,但最终发现,在未播放视频时,窗口确实是透明的,但是当开始播放视频后,窗口就不透明了,特此记录下本人最终的解决办法。

先看下效果图:

二、关键代码

2.1、透明窗口设置

2.1.1、构造函数中调用以下代码

setAttribute(Qt::WA_TranslucentBackground, true);
setWindowFlags(Qt::SplashScreen|Qt::FramelessWindowHint);

第一行,使透明背景生效,透明背景在paintEvent中设置;

第二行,Qt::SplashScreen,启动画面,原本使用的Qt::ToolTip标签,但是这个会导致窗口一直置顶,所以换成了Qt::SplashScreen。Qt::FramelessWindowHint让窗口无边框,窗口如果是其它控件的子控件,这句也可以不要;

2.1.2、重载paintEvent事件

void DigitalZoom::paintEvent(QPaintEvent *event)
    QPainter painter(this);
    painter.fillRect(this->rect(), QColor(0, 0, 0, 1));

2.2、视频播放窗口设置

2.2.1、调用透明窗口

mainWidget::mainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::mainWidget)

    ui->setupUi(this);

    m_digitalZoomWidget = new DigitalZoom(this);
    m_digitalZoomWidget->show();

2.2.2、透明窗口位置及大小自适应视频窗口

使用Qt::SplashScreen后,透明窗口的位置和大小就和其父窗口没有关系了,需要对位置进行转换,我这里因为透明窗口的父类是视频播放窗口,所以在视频播放窗口类中重载了moveEvent和resizeEvent事件。

void mainWidget::resizeEvent(QResizeEvent *event)

    m_digitalZoomWidget->resize(width(),height());


void mainWidget::moveEvent(QMoveEvent *event)

    m_digitalZoomWidget->move(geometry().x(),geometry().y());

2.2.3、坐标转换

本人因为需要实现数字放大功能,所以需要转换拉框坐标,这里就不列出了。


 三、所有源码

3.1、透明窗口

digitalzoom.h

#ifndef DIGITALZOOM_H
#define DIGITALZOOM_H

#include <QWidget>

class DigitalZoom : public QWidget

    Q_OBJECT
public:
    explicit DigitalZoom(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event) override;
    void mousePressEvent(QMouseEvent *event) override;
    void mouseMoveEvent(QMouseEvent *event) override;
    void mouseReleaseEvent(QMouseEvent *event) override;

signals:

public slots:

private:
    QPoint m_startPoint; /* 鼠标按下位置 */
    QPoint m_endPoint;  /* 鼠标移动后的位置 */
    bool m_bIsLeftMousePressMove = false; /* 鼠标左键按下移动标志 */
;

#endif // DIGITALZOOM_H

digitalzoom.cpp

#include "digitalzoom.h"
#include <QPainter>
#include <QPaintEvent>
#include <QLabel>

DigitalZoom::DigitalZoom(QWidget *parent) : QWidget(parent)

    setAttribute(Qt::WA_TranslucentBackground, true);
    setWindowFlags(Qt::SplashScreen|Qt::FramelessWindowHint);

    QLabel* upLab = new QLabel("我是透明窗口上的不透明控件",this);
    upLab->setStyleSheet("color:red");


void DigitalZoom::paintEvent(QPaintEvent *event)
    QPainter painter(this);
    if(m_bIsLeftMousePressMove)
        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setPen(QPen(QColor(0, 160, 230), 5));
        painter.drawRect(event->rect());
    else
        painter.fillRect(this->rect(), QColor(0, 0, 0, 1));
    


void DigitalZoom::mousePressEvent(QMouseEvent *event)

    if(event->buttons() & Qt::LeftButton)
    
        m_startPoint = event->pos();
    

    QWidget::mousePressEvent(event);


void DigitalZoom::mouseMoveEvent(QMouseEvent *event)

    if(event->buttons() & Qt::LeftButton)
        m_endPoint = event->pos();
        m_bIsLeftMousePressMove = true;
        update(QRect(m_startPoint,m_endPoint));
    


void DigitalZoom::mouseReleaseEvent(QMouseEvent *event)

    if(m_bIsLeftMousePressMove)
        m_bIsLeftMousePressMove = false;
    

    update();

3.2、视频播放窗口

 mainWidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include "digitalzoom.h"

namespace Ui 
class mainWidget;


class mainWidget : public QWidget

    Q_OBJECT

public:
    explicit mainWidget(QWidget *parent = nullptr);
    ~mainWidget();

protected:
    void resizeEvent(QResizeEvent *event) override;
    void moveEvent(QMoveEvent *event) override;

private:
    Ui::mainWidget *ui;
    DigitalZoom* m_digitalZoomWidget;
;

#endif // MAINWIDGET_H

mainWidget.cpp

#include "mainwidget.h"
#include "ui_mainwidget.h"

mainWidget::mainWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::mainWidget)

    ui->setupUi(this);

    /* play video start */
    //此处测试在当前窗口上通过winId()获取窗口句柄来播放视频
    /* play video stop */

    m_digitalZoomWidget = new DigitalZoom(this);
    m_digitalZoomWidget->show();


mainWidget::~mainWidget()

    delete ui;


void mainWidget::resizeEvent(QResizeEvent *event)

    m_digitalZoomWidget->resize(width(),height());


void mainWidget::moveEvent(QMoveEvent *event)

    m_digitalZoomWidget->move(geometry().x(),geometry().y());

 mainWidget.ui

默认生成,未作任何修改。

QT QMediaPlayer Widget导致小白窗口

【中文标题】QT QMediaPlayer Widget导致小白窗口【英文标题】:QT QMediaPlayer Widget causes small white window 【发布时间】:2014-02-08 22:58:56 【问题描述】:

我想在我的 .ui 表单文件的 qtabwidget 内添加一个视频播放器。当程序运行时(Windows 8),程序窗口是一个小白框(不是我的 .ui 表单),视频播放(你可以听到)。另外,如果我注释掉“ui->Information->addTab(videoWidget, “video”);”之后的所有内容程序的 UI 加载正常,新标签创建为“视频”,但是没有任何效果,因为 mediaPlayer 代码被注释掉了。这是媒体小部件的代码:

mainwin.h

private:
    QMediaPlayer * mediaPlayer;

mainwin.cpp

ui->setupUi(this);
mediaPlayer = new QMediaPlayer();
QVideoWidget *videoWidget = new QVideoWidget();
ui->Information->addTab(videoWidget, "video");
mediaPlayer->setVideoOutput(videoWidget);
mediaPlayer->setMedia(QUrl("link"));
mediaPlayer->play();

有人可以帮忙吗?谢谢!

编辑:查看 qt 中的示例,我在创建窗口时注意到“mediaPlayer(0, QMediaPlayer::VideoSurface)”,如果我这样做,我会得到:

Project::Project(QWidget *parent) :
QMainWindow(parent),
mediaPlayer(0, QMediaPlayer::VideoSurface),
ui(new Ui::Project)

ui->setupUi(this);

这会导致一些错误,“错误:表达式列表在 mem-initializer [-fpermissive] mediaPlayer(0, QMediaPlayer::VideoSurface) 中被视为复合表达式”,“警告:逗号运算符的左操作数无效 [ -Wunused-value]”和“错误:在初始化时无法将 'QMediaPlayer::Flag' 转换为 'QMediaPlayer*'”。

【问题讨论】:

可能与您的主要问题无关:您在构造函数中重新定义了 mediaPlayer。 @AlexP 所以 mainwin.cpp 中的第二行不需要在那里? 通过输入QMediaPlayer * mediaPlayer =,您在构造函数中重新声明了 mediaPlayer,这将有效地隐藏您的类变量。我编辑了你的问题文本(在其他用户批准后你会看到它)向你展示如何更改它,因为它比在 cmets 中描述它更容易。 @Alexp 好吧,我知道你在那里做了什么。谢谢。我的主要问题仍然没有解决。 是的,我有点想这个改变不会解决它。 (不过,总是值得一试,你知道吗?)如果我发现任何问题,我会多看看并发布答案。 【参考方案1】:

在我的 QT 5.5.0 项目中嵌入完整的 QT 媒体播放器示例后,我遇到了同样的问题。开始播放视频后,左上角会出现一个白框。

我注意到播放器实际上会使我的应用程序工具栏(部分)变白,但如果工具栏被隐藏,它会添加白色框。

由于我不需要工具栏,我通过删除工具栏来解决这个问题 而不是隐藏它。在 QT 设计器中,右键单击工具栏,然后单击“删除工具栏”。

【讨论】:

以上是关于Qt视频播放窗口叠加透明窗口的主要内容,如果未能解决你的问题,请参考以下文章

QT按钮如何打开本地视频

QT视频窗口自动跳出来的怎么设置不跳出来啊

QT解决视频透视,有阴影的方法

如何在 Qt 无框窗口中显示 GStreamer 视频?

如何在半透明的 QWidget 上播放视频?

qt中mpv的鼠标点击