上次说了《使用视频当背景1.0》,有的人必须使用视频当背景,但是上次的代码风险又颇多,那到底有没有办法解决呢?其实是有的,比较麻烦而已,话不多说,上代码:
最终画面代码
loginwidget.h
#ifndef LOGINWIDGET_H
#define LOGINWIDGET_H
#include <QWidget>
#include <QLabel>
#include <QResizeEvent>
#include "inforwindow.h"
#include "videowidget.h"
class LoginWidget : public QWidget
{
Q_OBJECT
public:
LoginWidget(QWidget *parent = 0);
~LoginWidget();
private:
VideoWidget *m_pVideoWidget = nullptr; //背景
InforWindow *m_pInforWindow = nullptr; //登录窗口
};
#endif // LOGINWIDGET_H
loginwidget.cpp
#include <QMovie>
#include "loginwidget.h"
LoginWidget::LoginWidget(QWidget *parent)
: QWidget(parent)
{
setMinimumSize(1000,800);
/*窗口背景*/
m_pVideoWidget = new VideoWidget(this);
/*登录窗口*/
m_pInforWindow = new InforWindow(m_pVideoWidget);
m_pInforWindow->setAttribute(Qt::WA_TranslucentBackground,true); //背景透明
m_pInforWindow->setWindowFlags(Qt::FramelessWindowHint
|Qt::WindowStaysOnTopHint);//无边框,置顶
m_pInforWindow->setGeometry(477,466,949,186);
}
LoginWidget::~LoginWidget()
{
delete m_pVideoWidget;
delete m_pInforWindow;
}
视频播放代码
videowidget.h
#ifndef VIDEOWIDGET_H
#define VIDEOWIDGET_H
#include <QMainWindow>
#include <QWidget>
#include <QPaintEvent>
#include <QImage>
#include <QTimer>
#include <cv.h>
#include <highgui.h>
#include <opencv2/opencv.hpp>
#include "inforwindow.h"
class VideoWidget : public QWidget
{
Q_OBJECT
public:
VideoWidget(QWidget *parent = 0);
~VideoWidget();
protected:
void paintEvent(QPaintEvent *e);
private slots:
void slot_nextFrame();
private:
InforWindow *m_pInforWindow = nullptr; //密码输入框
CvCapture *m_pCapture = nullptr;
IplImage *m_pIplImage = nullptr;
IplImage *m_pFrame = nullptr;
QImage *m_pImage = nullptr;
QTimer *m_pTimer = nullptr;
};
#endif // VIDEOWIDGET_H
videowidget.cpp
#include "videowidget.h"
#include <QPainter>
#include <QDebug>
VideoWidget::VideoWidget(QWidget *parent) : QWidget(parent)
{
m_pCapture = cvCaptureFromFile("../VideoWidget/test.mp4");
if (m_pCapture)
{
m_pFrame = cvQueryFrame(m_pCapture);
if (m_pFrame)
{
this->resize(m_pFrame->width,m_pFrame->height);
}
m_pImage = new QImage(QSize(m_pFrame->width,m_pFrame->height),
QImage::Format_RGB888);
m_pIplImage = cvCreateImageHeader(cvSize(m_pFrame->width,m_pFrame->height),8,3);
m_pIplImage->imageData = (char*)m_pImage->bits();
m_pTimer = new QTimer(this);
m_pTimer->setInterval(18);
connect(m_pTimer,SIGNAL(timeout()),this,SLOT(slot_nextFrame()));
m_pTimer->start();
}
}
VideoWidget::~VideoWidget()
{
cvReleaseImage(&m_pIplImage);
cvReleaseCapture(&m_pCapture);
delete m_pInforWindow;
delete m_pFrame;
delete m_pImage;
delete m_pTimer;
}
void VideoWidget::paintEvent(QPaintEvent *e)
{
QPainter painter(this);
painter.drawImage(QPoint(0,0),*m_pImage);
}
void VideoWidget::slot_nextFrame()
{
m_pFrame = cvQueryFrame(m_pCapture);
if(m_pFrame)
{
if(m_pFrame->origin == IPL_ORIGIN_TL)
{
cvCopy(m_pFrame,m_pIplImage,0);
}
else
{
cvFlip(m_pFrame,m_pIplImage,0);
}
cvCvtColor(m_pIplImage,m_pIplImage,CV_BGR2RGB);
this->update();
}
else
{
/*设置循环播放*/
cvReleaseImage(&m_pIplImage);
cvReleaseCapture(&m_pCapture);
delete m_pImage;
m_pCapture = cvCaptureFromFile("../VideoWidget/test.mp4");
if (m_pCapture)
{
m_pFrame = cvQueryFrame(m_pCapture);
if (m_pFrame)
{
this->resize(m_pFrame->width,m_pFrame->height);
}
m_pImage = new QImage(QSize(m_pFrame->width,m_pFrame->height), QImage::Format_RGB888);
m_pIplImage = cvCreateImageHeader(cvSize(m_pFrame->width,m_pFrame->height), 8,3);
m_pIplImage->imageData = (char*)m_pImage->bits();
m_pTimer->start();
}
}
}
登录界面代码
inforwindow.h
#ifndef INFORWINDOW_H
#define INFORWINDOW_H
#include <QWidget>
#include <QLineEdit>
#include <QLabel>
#include <QObject>
#include <QPushButton>
class InforWindow : public QWidget
{
Q_OBJECT
public:
InforWindow(QWidget *parent = 0);
~InforWindow();
private:
QLabel *m_pPasswordLabel = nullptr; //提示输入密码
QLabel *m_pInformationLabel = nullptr; //提示按回车
QLineEdit *m_pPasswordLineEdit = nullptr; //密码输入框
QPushButton *m_pIsVisibleBtn = nullptr; //设置密码是否可见按键
QPushButton *m_pConfirmBtn = nullptr; //确认按键
bool m_isVisible = false; //判断按钮状态标志
private slots:
void slot_isVisibleBtnClicked(); //是否可见按键响应函数
void slot_isConfirmBtnClicked(); //确认按键响应函数
};
#endif // INFORWINDOW_H
inforwindow.cpp
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <QFile>
#include <QDebug>
#include "inforwindow.h"
InforWindow::InforWindow(QWidget *parent)
: QWidget(parent)
{
QFile qssfile(":/style.qss");
qssfile.open(QFile::ReadOnly);
QString qss;
qss = qssfile.readAll();
this->setStyleSheet(qss);
m_pPasswordLabel = new QLabel(this);
QPixmap passwordPixmap(":/password.png");
m_pPasswordLabel->setPixmap(passwordPixmap);
m_pInformationLabel = new QLabel(this);
QPixmap pressEnterPixmap(":/pressenter.png");
m_pInformationLabel->setPixmap(pressEnterPixmap);
m_pPasswordLineEdit = new QLineEdit(this);
m_pPasswordLineEdit->setEchoMode(QLineEdit::Password);
connect(m_pPasswordLineEdit, SIGNAL(returnPressed()),
this,SLOT(slot_isConfirmBtnClicked()));
m_pIsVisibleBtn = new QPushButton(this);
if(!m_isVisible)
{
m_pIsVisibleBtn->setObjectName(tr("VisibleBtn"));
}
else
{
m_pIsVisibleBtn->setObjectName(tr("InVisibleBtn"));
}
m_pIsVisibleBtn->move(((this->width()*9.4)/1.3),(this->height()*5));
connect(m_pIsVisibleBtn,SIGNAL(clicked(bool)),
this,SLOT(slot_isVisibleBtnClicked()));
m_pConfirmBtn = new QPushButton(this);
m_pConfirmBtn->setObjectName(tr("ComfirmBtn"));
m_pConfirmBtn->move(((this->width()*9.4)/1.1),(this->height()*5));
connect(m_pConfirmBtn,SIGNAL(clicked(bool)),
this,SLOT(slot_isConfirmBtnClicked()));
m_pPasswordLabel->setGeometry(0,0,267,16);
m_pPasswordLineEdit->setGeometry(0,48,944,72);
m_pIsVisibleBtn->setGeometry(823,79,30,16);
m_pConfirmBtn->setGeometry(895,67,44,34);
m_pInformationLabel->setGeometry(828,142,113,15);
}
InforWindow::~InforWindow()
{
delete m_pPasswordLabel;
delete m_pInformationLabel;
delete m_pPasswordLineEdit;
delete m_pIsVisibleBtn;
delete m_pConfirmBtn;
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "loginwidget.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent=0);
~MainWindow();
private:
LoginWidget* m_pLoginWidget = nullptr;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
m_pLoginWidget = new LoginWidget;
m_pLoginWidget->show();
}
MainWindow::~MainWindow()
{
delete m_pLoginWidget;
}
qss内容
*{
background:transparent;
color: white
}
QLineEdit{
border-style: solid;
border-left-width: 0px;
border-right-width: 0px;
border-top-width: 0px;
border-bottom-width: 1px;
border-bottom-color: white;
font-family:"Microsoft YaHei";
font-size: 48px
}
QPushButton#VisibleBtn{
border-image: url(:/visible.png)
}
QPushButton#InVisibleBtn{
border-image: url(:/invisible.png)
}
QPushButton#ComfirmBtn{
border-image: url(:/confirm.png)
}
说明一下,因为QT QMediaPlayer机制的原因,所以底层播放不能使用QT QVideoWidget,于是这里使用了OpenCV,但是需要提前配置环境,比较麻烦,但是这个最为完美,不怕麻烦的可以尝试。
附上各种传送门:
使用动态图当背景图片:http://blog.csdn.net/fan_xingwang/article/details/79170087
使用视频当背景1.0:http://blog.csdn.net/fan_xingwang/article/details/79170463
最后,配置OpenCV环境,以下两个链接,请相互参考使用:
http://blog.csdn.net/zhaocj/article/details/38944037
http://blog.csdn.net/fang_chuan/article/details/52900834