1、Qt 子窗口嵌入到 父窗口中
新建一个简单类,继承于QWidget
class CPlayerWidget: public QWidget
{
public: CPlayerWidget(QWidget * pParent);
}
在类的构造函数中
CPlayerWidget::CPlayerWidget(QWidget * pParent):
m_iInit(E_FALSE)
{
/* 去掉窗口标题栏 */
setWindowFlags(Qt::CustomizeWindowHint|Qt::FramelessWindowHint);
/* 绑定父窗口 */
this->setParent(pParent);
/* 可选择是否隐藏 */
//hide();
}
这样就完成了子窗口嵌入到父窗口的问题了
2、SDL绑定到 Qt 窗口
设计的时候,总是想要 SDL 的窗口在 Qt 子窗口中显示,而非单独的窗口。
一般网上的 FFmpeg + SDL 教程都是这样创建窗口的
m_pSDLWindow = SDL_CreateWindow("Simplest ffmpeg player's Window",
SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
width, height, SDL_WINDOW_OPENGL);
但是 SDL_CreateWindow 这个函数创建的窗口是单独的,并不符合我们的需求。所以,下面是重点了:
在 SDL2.0 中(SDL1.0的方法与此不一样,自行研究),提供了一个函数 SDL_CreateWindowFrom(void * data) ,使用这个函数创建的窗口可以绑定到父窗口中,即不是单独的窗口,该函数形参 data 为要绑定的窗口 ID,在 Qt5 中,可以通过 winId() 来获得窗口 ID
m_pSDLWindow = SDL_CreateWindowFrom((void *)someWidget->winId());
这样就 SDL的显示窗口就绑定到指定的窗口上了。
在我原本的设计中,CPlayerWidget 类是视频播放类,在选择视频文件后,然后在 CPlayerWidget 类的方法里面创建SDL显示窗口并进行画面显示播放,但是,无论我尝试多少次,都无法出现画面,在网上也没找到相关的解决方法,如果将 SDL_CreateWindowFrom 改成 SDL_CreateWindow ,单独创建一个窗口,功能正常。
所以,划重点了,通过 SDL_CreateWindowFrom 创建的窗口有问题!
后来我将 SDL_CreateWindowFrom 这个函数调用放在父类的构造函数中,一切正常了 !
SkyPlayer::SkyPlayer(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::SkyPlayer)
{
ui->setupUi(this);
/* 设置窗口标题 */
this->setWindowTitle("SkyPlayer");
this->resize(960, 720);
/* 播放窗口 */
m_pPlayerWidget = new CPlayerWidget(this);
assert(NULL != m_pPlayerWidget);
if( SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER) )
{
printf( "Could not initialize SDL - %s\n", SDL_GetError());
}
/* 必须要放到构造函数初始化? */
m_pSDLWindow = SDL_CreateWindowFrom((void *)m_pPlayerWidget->winId());
}
在父类窗口中创建子窗口后(播放窗口),然后进行 SDL 初始化,并绑定 SDL 显示窗口,在选择视频文件后,将创建的窗口句柄 m_pSDLWindow 传入到CPlayerWidget 类的方法里面,画面出来了!
具体原因未知,可能是我用的不对吧,以此做个记录 !