mac 中qt获取窗口_SDL初识嵌入Qt窗口中实时绘制图片

本文介绍了在mac环境下,如何使用Qt结合SDL库来实现窗口的获取和图片的实时绘制。通过初始化SDL,嵌入Qt窗口,加载BMP图片并更新窗口表面,实现了高效地图像显示。由于Qt的QPaintEvent中绘制图片存在性能问题,作者选择使用SDL进行GPU渲染,以提高显示性能。
摘要由CSDN通过智能技术生成

目录

1、SDL介绍

2、实现效果

3、主要函数的作用

4、主要代码

5、完整代码

6、总结


1、SDL介绍

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

支持Windows,Mac OS X,Linux,iOS和Android,是一套开放源代码的跨平台开发库,功能强大,在音视频开发领域经常被使用到。

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

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

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

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

ee5171738879f81e74b92f5f90578a64.png

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

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

#include "SDL.h"

#undef main

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

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

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

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

0924111d46c6e2fbea7d2d7a328ff9b2.png

2、实现效果

74c51c800ca699b572fb1cfcb1a5ca2f.png

3、主要函数的作用

1、SDL_Init(SDL_INIT_EVERYTHING):

表示初始化SDL 

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

表示嵌入Qt窗口 

3、SDL_GetWindowSurface(_window):

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

4、SDL_LoadBMP("test.bmp"):

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

5、SDL_BlitSurface(_pload, NULL, _pScreens, NULL):

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

6、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;  }}

这里主要是初始化SDL,然后创建SDL绘制窗口。

//绘制图片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;  }}

读取bmp图片,讲图片信息设置到窗口上。

5、完整代码

#pragma once #include #include "ui_testSDL.h"#include #include "SDL.h"#undef  main  #pragma comment(lib,"SDL2.lib") #pragma comment(lib,"SDL2main.lib")#pragma comment(lib,"SDL2test.lib") #include 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格式,这是一个很耗时的操作,而且是在cpu层面做的处理,在4K的电脑显示器,显示图像就很吃力了,如果是视频的连续图像帧,那么会很卡顿,所以选择sdl来做,用gpu渲染。当前qt也有QOpenglWidget,不过使用起来并没有sdl方便。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值