作者:虚坏叔叔
博客:https://xuhss.com
早餐店不会开到晚上,想吃的人早就来了!
打开qt设计师
Qwidget
绘制视频效率低,可以使用OpenGl Widget
。
拖动OpenGl Widget
到窗口,修改名称为view
将打开按钮放到前面:
宽度和高度都调整为600*400
PyPlayer.cpp
中修改视口大小:
if (width > 0 && height > 0)
{
resize(width, height);
ui.view->resize(width, height);
}
为了控制opengl
窗口,需要提升view
在Visual studio
中添加类VideoView
用于重载widget
修改VideoView.h
#pragma once
#include
//Q_OBJECT表示自动会生成信号槽相关代码
class VideoView:public QOpenGLWidget
{
Q_OBJECT
public:
VideoView(QWidget *p = NULL);
~VideoView();
// 重载显示函数
void paintEvent(QPaintEvent *e);
public slots:
void SetImage(unsigned char* rgb); // 槽函数
signals:
void SetImageSig(unsigned char *rgb); // 信号函数
protected:
//存放显示图像
QImage *img = NULL;
};
修改VideoView.cpp
#include "VideoView.h"
#include
void VideoView::SetImage(unsigned char* rgb)
{
if (!rgb)return;
if (!img)
{
/// 本窗口宽度
uchar *buf = new uchar[width()*height() * 4];
// 宽高发生变化需要再次分配空间
img = new QImage(buf, width(), height(), QImage::Format_ARGB32);
}
uchar *bits = img->bits();
memcpy(bits, rgb, width()*height() * 4);
// 刷新显示
update();
}
// 重载显示函数
void VideoView::paintEvent(QPaintEvent *e)
{
if (!img || img->isNull()) return;
QPainter painter;
painter.begin(this);
painter.drawImage(QPoint(0, 0), *img);
painter.end();
}
VideoView::VideoView(QWidget *p):QOpenGLWidget(p)
{
QObject::connect(
this, SIGNAL(SetImageSig(unsigned char*)),
this, SLOT(SetImage(unsigned char*))
);
}
VideoView::~VideoView()
{
}
修改pyqt.py
,调用SetImage来在线程中显示图像
isRunning = True
#输出的宽高,根据窗口尺寸
winWidth = 1280
winHeight = 720
#主函数 在子线程中调用,线程是c++创建
def main():
print("Python main")
global ff;
global winWidth;
global winHeight;
while isRunning:
#解封装
re = ff.read()
if re:
print(".", end='', flush = True) #flush输出缓冲
#解码图像
re = ff.decode(winWidth, winWidth)
print(re, end='', flush = True)
#显示图像
if re:
SetImage(ff)
time.sleep(0.02)
else:
time.sleep(1)
修改PyPlayer.cpp
添加函数SetImage
,用于被python调用
#include
#include "PyPlayer.h"
#include
#include
#include
#include "PyFFmpeg.h"
#include "XFFmpeg.h"
using namespace std;
static PyObject *pModule = 0;
static VideoView *view = 0;
PyObject *SetImage(PyObject *self, PyObject *arg)
{
PyFFmpeg *obj = (PyFFmpeg *)arg;
view->SetImageSig( obj->ff->rgb);
Py_RETURN_TRUE;
}
这里需要引入PyFFmpeg
头文件路径
..\PyFFmpeg_qt
由于需要用到rgb
,所以需要在XFFmpeg.h
中,将rgb
改为public变量
在PyPlayer.cpp
构造函数中注册进去,这样python才能g狗调用到
Py_XDECREF(conf);
// 开放选择文件的接口给python
static PyMethodDef meths[] = {
{ "OpenDialog", (PyCFunction)OpenDialog, METH_NOARGS, 0 }
,{ "SetImage", (PyCFunction)SetImage, METH_O, 0 } // 一个参数
,{ NULL }
};
在PyPlayer
类中,需要控制播放器窗口,所以定义一个静态view,然后在构造函数中初始化它:
PyPlayer::PyPlayer(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);
view = ui.view;
运行:
点赞
收藏
转发
一波哦,博主也支持为铁粉丝制作专属动态壁纸哦~学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
Python实战微信订餐小程序 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
Python量化交易实战 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
❤️ C++ QT结合FFmpeg实战开发视频播放器❤️ | 难度偏高 | 分享学习QT成品的视频播放器源码,需要有扎实的C++知识! |
游戏爱好者九万人社区 | 互助/吹水 | 九万人游戏爱好者社区,聊天互助,白嫖奖品 |
Python零基础到入门 | Python初学者 | 针对没有经过系统学习的小伙伴,核心目的就是让我们能够快速学习Python的知识以达到入门 |
关注下面卡片即刻获取更多编程知识,包括各种语言学习资料,上千套PPT模板和各种游戏源码素材等等资料。更多内容可自行查看哦!