QWidget播放视频背景图片闪烁

scorlw 发布于

QWidget播放视频背景图片闪烁

Qt

把QLabel的句柄传入海康的SDK进行显示视频时,当软件失去焦点或者重新获得焦点时,会闪烁一下的问题.

设置 QLabel:

1
2
3
QLabel->setAttribute(Qt::WA_OpaquePaintEvent);

QLabel->setUpdatesEnabled(false);

这样就可以避免闪烁了。

播放软件主窗口重新实现函数changeEvent,解决最小化之后界面不刷新问题。

1
2
3
4
5
6
7
8
void VRS::changeEvent(QEvent * event)
{
//最小化之后再恢复到之前状态,界面会出现不update的问题,下面这段代码解决此问题
if( event->type() == QEvent::WindowStateChange)
{
this->setAttribute(Qt::WA_Mapped);
}
}

播放软件实现了多窗口同时播放多路视频。在切换不同的视频窗口时出现背景图片刷新闪屏。

播放视频的widget类派生自QWidget,重新实现paintEvent函数,绘制背景图片。

1
2
3
4
5
6
7
8
9
void CSSAWidget::paintEvent(QPaintEvent *)
{
////由于继承了QWidget,必须重载paintevent才能绘制背景
QStyleOption opt;
opt.initFrom(this);
QPainter p(this);
style()->drawPrimitive(QStyle::PE_Widget, &opt, &p, this);
p.drawPixmap(0, 0, width(), height(), m_pixMapBG);//绘制背景
}

问题是在视频播放过程中,当播放软件重绘的时候(比如调用update、repaint等函数时),会重绘widget背景,导致播放视频闪烁。

  • 结合网上查找方案和Qt官方文档之后,设置widget属性setAttribute(Qt::WA_OpaquePaintEvent); 之后,在软件上进行其他窗口切换的时候不再刷新背景。
    Qt官方文档解释如下:To rapidly update custom widgets that constantly paint over their entire areas with opaque content, e.g., video streaming widgets, it is better to set the widget’s Qt::WA_OpaquePaintEvent, avoiding any unnecessary overhead associated with repainting the widget’s background.快速刷新需要在整个窗口区域持续绘制不透明内容自定义widget,比如视频流widget,最好设置Qt::WA_OpaquePaintEvent属性来避免任何不必要的过度重绘背景。

    Qt::WA_OpaquePaintEvent属性的解释如下:Indicates that the widget paints all its pixels when it receives a paint event. Thus, it is not required for operations like updating, resizing, scrolling and focus changes to erase the widget before generating paint events. The use of WA_OpaquePaintEvent provides a small optimization by helping to reduce flicker on systems that do not support double buffering and avoiding computational cycles necessary to erase the background prior to painting. Note: Unlike WA_NoSystemBackground, WA_OpaquePaintEvent makes an effort to avoid transparent window backgrounds. This flag is set or cleared by the widget’s author.

  • 虽然使用上述方法,当操作一直在软件上时不再出现重绘背景的问题。但是当软件失去焦点,再重新获取焦点时,依旧会出现重绘背景。经过调查后发现一种解决方法:在视频播放开始后调用函数setUpdatesEnabled(false)设置widget不刷新,在视频播放结束之后调用函数setUpdatesEnabled(true)设置widget刷新。这种方式能够完全避免播放视频过程中背景闪现问题。

原文地址:https://blog.csdn.net/st_spring/article/details/88915828

https://blog.csdn.net/u013617648/article/details/70159933