2008年11月18日星期二

如何让SDL窗口嵌入Qt窗口

先简单介绍一下SDL:

SDL(Simple DirectMedia Layer)是一套开放原始码的跨平台多媒体开发函式库,使用C语言写成。SDL提供了数种控制图像、声音、输出入的函式,让开发者只要用相同或是相似的程式码就可以开发出跨多个平台(Linux、Windows、Mac OS X等)的应用软体。目前SDL多用于开发游戏、模拟器、媒体播放器等多媒体应用领域。
虽然SDL时常被比较为‘跨平台的DirectX’,然而事实上SDL是定位成以精简的方式来完成基础的功能,它大幅度简化了控制图像、声音、输出入等工作所需撰写的程式码。但更高阶的绘图功能或是音效功能则需搭配OpenGL和OpenAL等API来达成。另外它本身也没有方便建立GUI的函式。

但是如何让SDL窗口嵌入Qt的Widget里(render videos, audioes and images under GUI(made of Qt) using SDL. The sdl screen must be successfully integrated into qt screen.) ?
(Implement SDL in a QT widget-- how to integrate SDL into Qt? )
有两种方法用于解决这个问题,一个是间接法如 solution 1 ,一个是直接法如 solution 2. 以下是从网上收集的说明。

Solution 1: Using a seperate thread for rendering:

The easiest and sanest solution would be to decouple both parts. So that SDL and Qt run in separate processes and have them use some kind of messaging to communicate. SDL can be rendered into borderless window and the editor sends commands via messages.

using a seperate thread for rendering.
This thread could run on its own in the background and you simply could use your Qt-buttons to stop/pause/resume the thread.

If you want your SDL-window to react when a real key is pressed, it would be a viable solution to simulate key events from Qt.

If you want to just signal the SDL-code in some way I'd suggest using custom events (SDL_UserEvent).
For example, do something like this:

  1. Start App and open Qt-Window
  2. Initialize SDL and open output window
  3. Create thread that updates SDL-Window waits for some signal to stop/pause/resume or for xx seconds
  4. Use the SLOTs called by your Qt-Buttons to signal the thread to stop/pause/resume (using Key- or UserEvents? or using flags being set by Qt's main-thread) [/list=1]
Solusion 2: Direct way to integrate SDL into Qt:

put the SDL overlay window on the top of Qt window by using the following 3 steps.
1) create SDL window according to the size of Qt window.
2) create SDL window without frame (SDL_NOFRAME).
3) move SDL window based on the top-right coop. of SDL window (xMoveWindow())

Following functions from SDL are mainly used,
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
SDL_GetWMInfo(&info);
p_container->embed(info.info.x11.wmwindow, false).

没有评论: