- <span style="font-family: Arial, Verdana, sans-serif; white-space: normal; background-color: rgb(255, 255, 255); ">用的是widnowsXP的系统。给播放器中加入SDL的窗口的目的是为了播放视频,为了使用ffmpeg。</span>
当然了直接用QT+ffmpeg也可以,不过我目前还不会。而且QT就是个壳,SDL+ffmpeg才是想要表达的重点。
因为GTK+SDL+ffmpeg也是可以的。
windows上的Unix环境用的是MinGW,把SDL的库装到这个mingw目录下,对应的lib和include,跟下面一样。
然后在QT的creator里就可以用-lSDL这种了,并且可以包含<SDL/SDL.h>了。如果不行,看看环境变量里面的路径什么的包含对了么。
程序就是基于上一篇播放器的外壳进行增加的。增量式开发,~增一点一点~安全第一~~O(∩_∩)O~
主要是对于MyWindow那个class里面增加方法,也就是函数,然后在构造函数中调用函数来初始化SDL的窗口。
如何关联QT的widget和SDL的窗口是个关键,说实话没有好的办法,SDL的官网上也是用的这种很山寨的办法,就是提供什么窗口ID。
- /* SDL_Surface对象,作为一块graphical memory存在,用于进行绘制 */
- SDL_Surface *pSDLSurface;
- /* 把一个QT的窗口交给SDL使用 */
- void MyWindow::CreateSDLWindow(void)
- {
- QWidget *widget = ui->SDLWindow;
- {
- char winID[32] = {0};
- /* 获取窗口的大小 */
- QSize size = ui->SDLWindow->baseSize();
- sprintf(winID, "SDL_WINDOWID=0x%lx", (long unsigned int)widget->winId());
- SDL_putenv(winID);
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
- qDebug("Cannot initialize SDL.");
- }
- pSDLSurface = SDL_SetVideoMode(size.width(), size.height(), 0, SDL_HWSURFACE);
- if (!pSDLSurface) {
- qDebug("SDL Cannot set video mode");
- }
- }
- }
- SDL_WINDOWID=0x%lx
给赋值了,然后用SDL_putenv来给了环境变量,话说我是真不知道这个东西怎么传递的,而且在Linux下还是用的putenv()的函数。~~所谓的hack方法。
搞完了这个之后,运行程序就会看到原来灰白色的主窗口现在变成了黑色的。说明~成功了,下一步就可以在这个上面用一些SDL的东西来搞搞了。
最后把代码都贴上来吧,没改动的就算了。
mainwidnow.h
- #ifndef MAINWINDOW_H
- #define MAINWINDOW_H
- #include <QMainWindow>
- #include <QFileDialog>
- #include <QMessageBox>
- #include <stdio.h>
- #include <SDL/SDL.h>
- #define FILE_NAME_LENGTH 128
- extern SDL_Surface *pSDLSurface;
- namespace Ui {
- class MyWindow;
- }
- class MyWindow : public QMainWindow
- {
- Q_OBJECT
- public:
- explicit MyWindow(QWidget *parent = 0);
- ~MyWindow();
- /* 获取当前播放还是暂停的状态 */
- int getPlayState(void);
- /* 设置当前播放还是暂停的状态 */
- void setPlayState(int i);
- private:
- Ui::MyWindow *ui;
- /* 表示当前是播放还是暂停的状态的变量 */
- int iPlayPause;
- /* 表示要播放的文件名称 */
- char caFileName[FILE_NAME_LENGTH];
- /* 保存打开的文件名称(包括路径) */
- void SaveFileName(QString file);
- /* 获取文件名称(包括路径) */
- char *GetFileName(void);
- void CreateSDLWindow(void);
- public slots:
- /* 快退 */
- void SlotsBackward(void);
- /* 快进 */
- void SlotsForward(void);
- /* 播放暂停 */
- void SlotsPlayPause(void);
- /* 停止 */
- void SlotsStop(void);
- /* 打开文件选择对话框 */
- void SlotsOpenFile(void);
- };
- #endif // MAINWINDOW_H
mainwindow.cpp
-
- #include "mainwindow.h"
- #include "ui_mywindow.h"
- MyWindow::MyWindow(QWidget *parent) :
- QMainWindow(parent),
- ui(new Ui::MyWindow)
- {
- ui->setupUi(this);
- Qt::WindowFlags flags = 0;
- flags |= Qt::WindowMinimizeButtonHint; /* 禁止最大化 */
- setWindowFlags(flags);
- //QSize size = ui->MyScreen->baseSize();
- //setFixedSize(size.width(),size.height());
- setFixedSize(400,450); /* 禁止改变窗口大小 */
- iPlayPause = 0;
- connect(ui->Backward, SIGNAL(clicked()), this, SLOT(SlotsBackward()));
- connect(ui->Forward, SIGNAL(clicked()), this, SLOT(SlotsForward()));
- connect(ui->PlayPause, SIGNAL(clicked()), this, SLOT(SlotsPlayPause()));
- connect(ui->Stop, SIGNAL(clicked()), this, SLOT(SlotsStop()));
- connect(ui->OpenFile, SIGNAL(clicked()), this, SLOT(SlotsOpenFile()));
- CreateSDLWindow();
- }
- MyWindow::~MyWindow()
- {
- delete ui;
- }
- /* 快退 */
- void MyWindow::SlotsBackward(void)
- {
- qDebug("Backward");
- }
- /* 快进 */
- void MyWindow::SlotsForward(void)
- {
- qDebug("Forward");
- }
- /* 第一次点下去从播放变为暂停,以后每次布尔状态切换播放和暂停状态 */
- void MyWindow::SlotsPlayPause(void)
- {
- if (getPlayState()==0) {
- qDebug("Play: %s", GetFileName());
- setPlayState(1);
- } else {
- qDebug("Pause");
- setPlayState(0);
- }
- }
- /* 停止当前的播放 */
- void MyWindow::SlotsStop(void)
- {
- qDebug("Stop");
- }
- /* 获取当前的播放状态,播放还是暂停 */
- int MyWindow::getPlayState(void)
- {
- return iPlayPause;
- }
- /* 设置当前的播放状态,播放还是暂停 */
- void MyWindow::setPlayState(int i)
- {
- iPlayPause = i;
- }
- /* 与OPEN按钮关联的动作,显示文件选择对话框,让用户选择想要打开的文件 */
- void MyWindow::SlotsOpenFile(void)
- {
- qDebug("Open File");
- QFileDialog *fd = new QFileDialog(this);
- fd->setModal(QFileDialog::ExistingFile); /* 设置模式为存在的文件 */
- fd->setViewMode(QFileDialog::Detail); /* 设置显示模式为详细 */
- fd->setFilter("Video (*.mpeg *.avi)"); /* 设置过滤器,显示特定后缀名的文件 */
- if (fd->exec() == QDialog::Accepted) {
- QString file = fd->selectedFiles()[0]; /* 取得选择的文件,包括了绝对路径 */
- //qDebug(file.toAscii().data());
- SaveFileName(file);
- }
- }
- /* 将想要打开的媒体文件的名字保存到一个数组里面,方便使用 */
- void MyWindow::SaveFileName(QString file)
- {
- memset(caFileName, 0, FILE_NAME_LENGTH);
- strcpy(caFileName, file.toAscii().data());
- }
- /* 获取想要打开的媒体文件的名字 */
- char* MyWindow::GetFileName(void)
- {
- return caFileName;
- }
- /* SDL_Surface对象,作为一块graphical memory存在,用于进行绘制 */
- SDL_Surface *pSDLSurface;
- /* 把一个QT的窗口交给SDL使用 */
- void MyWindow::CreateSDLWindow(void)
- {
- QWidget *widget = ui->SDLWindow;
- {
- char winID[32] = {0};
- /* 获取窗口的大小 */
- QSize size = ui->SDLWindow->baseSize();
- sprintf(winID, "SDL_WINDOWID=0x%lx", (long unsigned int)widget->winId());
- SDL_putenv(winID);
- if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER)) {
- qDebug("Cannot initialize SDL.");
- }
- pSDLSurface = SDL_SetVideoMode(size.width(), size.height(), 0, SDL_HWSURFACE);
- if (!pSDLSurface) {
- qDebug("SDL Cannot set video mode");
- }
- }
- }