Qt视频播放窗口叠加透明窗口
Posted 秦时小
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Qt视频播放窗口叠加透明窗口相关的知识,希望对你有一定的参考价值。
前言
本人在做一个视频监控项目时,遇到了透明窗口无法透明的问题,特记录下解决过程。
更新:经测试,本文提到的方法用于多分屏复杂的视频播放窗口时有问题。
目录
一、需求
在视频播放界面上,叠加一个透明窗口,实现拉框局部放大功能。
本来以为这个很简单,直接给窗口加一个透明设置项就行,但最终发现,在未播放视频时,窗口确实是透明的,但是当开始播放视频后,窗口就不透明了,特此记录下本人最终的解决办法。
先看下效果图:
二、关键代码
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视频播放窗口叠加透明窗口的主要内容,如果未能解决你的问题,请参考以下文章