Qt实现 SDL嵌入Qt窗口中绘制图片

2 篇文章 2 订阅

目录

1、SDL介绍

2、实现效果

3、主要函数的作用

4、主要代码

5、完整代码

6、总结


1、SDL介绍

SDL用C编写,可与C ++一起使用,并且可用于其他几种语言,如C#和Python,

支持Windows,Mac OS X,Linux,iOS和Android,是一套开放源代码的跨平台开发库。

SDL多用于开发媒体播放器、游戏等多媒体应用领域,不仅支持绘制图片,还支持播放视频、音频,

它的底层实际是封装了opengl和directx,使用gpu渲染,不会占用过多的cpu。

首先需要下载SDL,引入其头文件和库

SDL下载地址:http://www.libsdl.org/

因为我是用vs2015开发,所以下载的是上面这个。

首先在代码中需要引入SDL头文件和库。

#include "SDL.h"
#undef  main


#pragma comment(lib,"SDL2.lib") 
#pragma comment(lib,"SDL2main.lib")
#pragma comment(lib,"SDL2test.lib")

加上#undef  main的目的是为了防止出现以下错误

2、实现效果

3、主要函数的作用

SDL_Init(SDL_INIT_EVERYTHING):

表示初始化SDL

 

SDL_CreateWindowFrom((void*)this->winId()):

表示嵌入Qt窗口

 

SDL_GetWindowSurface(_window):

获取与窗口相关联的像素信息

 

SDL_LoadBMP("test.bmp"):

是一个宏,作用是读取一个BMP图片 

 

SDL_BlitSurface(_pload, NULL, _pScreens, NULL):

也是一个宏,目的是执行从源像素到目标像素的传输。

 

SDL_UpdateWindowSurface(_window):

将窗口复制到屏幕上

4、主要代码

//初始化
void Init() {
	if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
		cout << "SDL_Init failed" << endl;
		return;
	}
	_window = SDL_CreateWindowFrom((void*)this->winId());
	if (!_window) {
		cout << "DL_CreateWindowFrom failed" << endl;
		return;
	}
}
//绘制图片
void timerEvent(QTimerEvent *event)
{
	_pScreens = SDL_GetWindowSurface(_window);
	if (!_pScreens) {
		cout << "SDL_GetWindowSurface failed" << endl;
	}
	_pload = SDL_LoadBMP("test.bmp");
	if (!_pload) {
		cout << "SDL_LoadBMP failed" << endl;
		return;
	}
	SDL_BlitSurface(_pload, NULL, _pScreens, NULL);
	if (SDL_UpdateWindowSurface(_window) < 0) {
		cout << "SDL_UpdateWindowSurface failed" << endl;
	}
}

 

5、完整代码

#pragma once

#include <QtWidgets/QWidget>
#include "ui_testSDL.h"
#include <QTimerEvent>
#include "SDL.h"
#undef  main


#pragma comment(lib,"SDL2.lib") 
#pragma comment(lib,"SDL2main.lib")
#pragma comment(lib,"SDL2test.lib")

#include <iostream>
using namespace std;

class testSDL : public QWidget
{
    Q_OBJECT

public:
	testSDL(QWidget *parent = Q_NULLPTR):_window(nullptr),
		_pScreens(nullptr),_pload(nullptr)
	{
		ui.setupUi(this);
		Init();
		startTimer(50);
	}
	~testSDL() {
		SDL_FreeSurface(_pload);
		SDL_DestroyWindow(_window);
		SDL_Quit();
	}
	void Init() {
		if (SDL_Init(SDL_INIT_EVERYTHING) < 0) {
			cout << "SDL_Init failed" << endl;
			return;
		}
		_window = SDL_CreateWindowFrom((void*)this->winId());
		if (!_window) {
			cout << "DL_CreateWindowFrom failed" << endl;
			return;
		}
	}
	void timerEvent(QTimerEvent *event)
	{
		_pScreens = SDL_GetWindowSurface(_window);
		if (!_pScreens) {
			cout << "SDL_GetWindowSurface failed" << endl;
		}
		_pload = SDL_LoadBMP("test.bmp");
		if (!_pload) {
			cout << "SDL_LoadBMP failed" << endl;
			return;
		}
		SDL_BlitSurface(_pload, NULL, _pScreens, NULL);
		if (SDL_UpdateWindowSurface(_window) < 0) {
			cout << "SDL_UpdateWindowSurface failed" << endl;
		}
	}
private:
    Ui::testSDLClass ui;
	SDL_Window *_window;
	SDL_Surface *_pScreens;
	SDL_Surface *_pload;
};

6、总结

原先是在QPaintEvent中绘制的,但是图片只显示一下就没了,并没有达到效果,原因可能是将sdl绘制嵌入qt后,qt窗口的焦点被sdl抢占的原因。所以这里改用定时器绘制。

其实qt内部提供了QPaint绘制图像,但是qimage显示图像,需要将数据转为rgb格式,这是一个很耗时的操作,在4K的电脑显示器,显示图像就很吃力了,如果是视频的图像帧,

那么会很卡顿,所以选择sdl来做。当前qt也有QOpenglWidget,不过使用起来并没有sdl方便。

 

人生苦短,总结不易,如果这篇文章可以帮助到你,请轻轻移动一下鼠标,把它顶(赞)起来,分享给更多的需要的伙伴。

  • 10
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
### 回答1: 要在Qt嵌入SDL2窗口,首先需要进行一些准备工作。首先,确保已经安装了QtSDL2,并且你的项目是一个Qt项目。 在Qt项目,创建一个新的Qt窗口类,例如“MainWindow”,并在该类的构造函数进行初始化。如下所示: ``` MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { // 设置窗口标题等 // 创建一个QWidget,作为SDL2窗口的父容器 QWidget *sdlContainer = new QWidget(this); setCentralWidget(sdlContainer); // 获取SDL窗口的句柄 SDL_Window *sdlWindow = SDL_CreateWindowFrom((void *)sdlContainer->winId()); } ``` 在上面的代码,我们首先创建一个QWidget作为SDL2窗口的父容器,并将其设置为主窗口窗口。然后,我们使用Qt的winId()函数获取sdlContainer的窗口句柄,并将其传递给SDL_CreateWindowFrom函数,从而创建一个SDL窗口。 接下来,我们可以将SDL渲染器渲染到这个窗口。我们需要在主窗口添加一个paintEvent事件,用于处理窗口重绘。如下所示: ``` void MainWindow::paintEvent(QPaintEvent *event) { // 在窗口重绘时,将SDL渲染器绘制窗口SDL_Renderer *sdlRenderer = SDL_CreateRenderer(sdlWindow, -1, 0); SDL_RenderClear(sdlRenderer); // 在这里进行SDL渲染器的渲染操作,例如绘制图形、绘制图片SDL_RenderPresent(sdlRenderer); // 调用父类的绘图事件处理函数 QMainWindow::paintEvent(event); } ``` 在上面的代码,我们创建一个SDL渲染器,并在paintEvent事件进行渲染操作。请注意,在窗口重绘之前,需要先清除渲染器,然后再进行绘制操作,最后调用SDL_RenderPresent函数将渲染结果显示到窗口上。 通过以上步骤,你可以在Qt成功嵌入SDL2窗口并进行渲染操作。记得在程序结束时要释放SDL的资源,以避免内存泄漏。 ### 回答2: 将Qt框架与SDL2窗口嵌入可以通过以下步骤实现: 首先,在Qt应用程序创建一个QWidget对象。例如,可以使用QMainWindow或QDialog来创建一个窗口。 接下来,使用QNativeWindow类将QWidget转换为原生的窗口句柄。可以通过调用QWidget的winId()函数来获取窗口的原生句柄。 然后,使用SDL_CreateWindowFrom函数将窗口的原生句柄传递给SDL2库以创建一个与Qt窗口相关联的SDL窗口。这样,SDL窗口就会嵌入Qt窗口。 在创建SDL窗口后,我们可以使用SDL_Renderer以及其他SDL函数来在SDL窗口绘制图形、处理输入事件等操作。 最后,需要在Qt应用程序的事件循环处理SDL2窗口的事件。通过使用QObject::startTimer()函数,我们可以将SDL2窗口的事件与Qt应用程序的事件循环相集成,以确保正确地处理事件。 在嵌入SDL2窗口时,还要注意一些限制。由于SDL2和Qt的事件处理机制不同,需要进行一些额外的处理,以确保事件正确传递和处理。另外,还需要注意窗口尺寸、位置等方面的调整,以确保SDL2窗口正确地嵌入Qt窗口。 总之,通过以上步骤,我们可以成功地在Qt应用程序嵌入SDL2窗口,并实现SDL2相关的图形和输入处理。这种嵌入方式可以帮助我们在使用Qt框架的同时,获得SDL2库强大的图形和输入能力,以满足特定应用需求。 ### 回答3: 要将Qt嵌入SDL2窗口,需要进行以下步骤: 1. 首先,确保已安装好QtSDL2,并准备好Qt项目开发环境。 2. 创建一个Qt窗口应用程序项目,选择“Widgets应用程序”类型。 3. 在Qt的主窗口设计界面,添加一个QWidget小部件作为SDL2窗口的容器。 4. 将SDL2窗口嵌入到QWidget容器,可以通过使用SDL_CreateWindowFrom函数或者SDL2函数来实现。 5. 创建一个QTimer对象,在定时器的槽函数通过SDL_RenderPresent函数或者SDL2函数来绘制SDL2窗口。 6. 编写Qt程序的其他逻辑,包括处理用户输入、更新SDL2窗口内的内容等。 7. 构建和运行Qt程序,即可看到SDL2窗口嵌入Qt窗口的效果。 需要注意的是,SDL2和Qt都是强大的图形库,彼此之间的使用存在一定的复杂性和潜在的冲突。在嵌入过程可能会遇到一些问题,如窗口大小和信号传递等方面的兼容性问题。因此,在实际应用需要仔细评估项目需求和技术复杂度,并进行充分的测试和调试,以确保嵌入的正确性和稳定性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值