QT配合SDL渲染一幅图像

环境配置

1.SDL配置

下载源码:http://www.libsdl.org/download-2.0.php

进入到 SDL2-2.0.14\VisualC 用visual studio 2019 打开 SDL.sln

将工程升级到vs2019选择对的,debug|release x64|x86进行编译生成相应的.dll.pdb.lib

然后将对应的.dll.pdb.lib放到对应目录中,并配置值相应的工程目录

2.QT配置

下载Qt安装包:https://www.qt.io/download(下载opensource版)  清华镜像  https://mirrors.tuna.tsinghua.edu.cn/  

QT配合SDL渲染一幅图像

下载qt目录下的对应版本双击安装,中途需要登录qt的官网账号,安装时需要安装Qtcreat组件。

QT配合SDL渲染一幅图像

QT配合SDL渲染一幅图像

进入vsaddin目录再下载和vs版本相匹配的Qt Vs插件安装。

QT配合SDL渲染一幅图像


进入VS安装管理器的界面,安装需要环境依赖。

QT配合SDL渲染一幅图像

QT配合SDL渲染一幅图像


3.vs创建Qt工程

使用VS创建工程,选择QT模板

QT配合SDL渲染一幅图像

选择响应的QT版本

QT配合SDL渲染一幅图像

创建QT文件,注意勾选文件名小写,保证工程在不同系统上的迁移

QT配合SDL渲染一幅图像

管理Qt版本

QT配合SDL渲染一幅图像

QT配合SDL渲染一幅图像

API介绍

重载定时器函数,在Qt类头文件中声明

#pragma once

#include <QtWidgets/QWidget>
#include "ui_sdlqtrgb.h"

class SdlQtrgb : public QWidget
{
    Q_OBJECT

public:
    SdlQtrgb(QWidget *parent = Q_NULLPTR);
    void timerEvent(QTimerEvent* ev) override;  //重载函数后,需要再后边注明 override 防止出错

private:
    Ui::SdlQtrgbClass ui;
};

在初始化Qt类函数的最后调用startTime循环调用,则初始化完Qt类后,每隔10ms就调用一次

SdlQtrgb::SdlQtrgb(QWidget *parent)
    : QWidget(parent)
{
    ......

    startTimer(10);
}

代码样例

头文件

#pragma once

#include <QtWidgets/QWidget>
#include "ui_sdlqtrgb.h"

class SdlQtrgb : public QWidget
{
    Q_OBJECT

public:
    SdlQtrgb(QWidget *parent = Q_NULLPTR);
    void timerEvent(QTimerEvent* ev) override;

private:
    Ui::SdlQtrgbClass ui;
};

类的定义

#include "sdlqtrgb.h"
#include<sdl2/SDL.h>
#include<iostream>
#include<qmessagebox.h>
#pragma comment(lib,"SDL2.lib")

//定义SDL全局变量
static SDL_Window* sdl_win = NULL;
static SDL_Renderer* sdl_render = NULL;
static SDL_Texture* sdl_texture = NULL;
static int sdl_width = 0;
static int sdl_height = 0;
static int pixsel_size = 4;
static unsigned char* rgb = NULL;


//定义Qt类的初始化函数,其中对SDL的固定属性配置进行初始化
SdlQtrgb::SdlQtrgb(QWidget *parent)
    : QWidget(parent)
{
    ui.setupUi(this);
    //sdl_width = ui.label->width();
    //sdl_height = ui.label->height();


    //1.初始化SDL库
    if (SDL_Init(SDL_INIT_VIDEO))
    {
        std::cout << SDL_GetError() << std::endl;
        return;
    }
   
    //2.创建窗口
    sdl_win = SDL_CreateWindowFrom((void*)ui.label->winId()); //将窗口与QT中的类绑定
    if (!sdl_win)
    {
        std::cout << SDL_GetError() << std::endl;
        return;
    }

    //3.创建渲染器
    sdl_render = SDL_CreateRenderer(sdl_win, -1, SDL_RENDERER_ACCELERATED);
    if (!sdl_render)
    {
        std::cout << SDL_GetError() << std::endl;
        return;
    }


    QImage img1("1.jpeg"); QImage img2("2.jpeg");
    if (img1.isNull() || img2.isNull())
    {
        QMessageBox::information(this,"","open image failed!");
        return;
    }
    //做数据对齐
    int out_w = img1.width() + img2.width();
    int out_h = img1.height() < img2.height()  ? img2.height() : img1.height();
  
    
       
    //改变窗口大小

    sdl_height = out_h;
    sdl_width = out_w;
    ui.label->move(0, 0);
    ui.label->resize(sdl_width, sdl_height);

    //4.创建纹理
    sdl_texture = SDL_CreateTexture(sdl_render,
        SDL_PIXELFORMAT_ABGR8888,
        SDL_TEXTUREACCESS_STREAMING,
        sdl_width,
        sdl_height
    );
    if (!sdl_texture)
    {
        std::cout << SDL_GetError() << std::endl;
        return;
    }
    rgb = new unsigned char[sdl_width * sdl_height * pixsel_size];

    //合并两幅图像,默认设置为透明
    memset(rgb, 0, sdl_width * sdl_height * pixsel_size);

    for (int i = 0; i < sdl_height; i++)
    {
        int b = i * sdl_width * pixsel_size;
        if (i < img1.height())
            memcpy(rgb + b, img1.scanLine(i), img1.width() * pixsel_size);
        b += img1.width()*pixsel_size;
        if (i < img2.height())
            memcpy(rgb + b, img2.scanLine(i), img2.width() * pixsel_size);
    }
    startTimer(10); //调用定时器函数

}

//定时器函数,在其中调用SDL对图像进行循环渲染
void SdlQtrgb::timerEvent(QTimerEvent* ev)
{
    //static unsigned char tmp = 255;
    //tmp--;
    //for (int j = 0; j < sdl_height; j++)
    //{
    //    int b = j * sdl_width * pixsel_size;
    //    for (int i = 0; i < sdl_width * pixsel_size; i += pixsel_size)
    //    {
    //        rgb[b + i] = 0; //B
    //        rgb[b + i + 1] = 255 - tmp; //G
    //        rgb[b + i + 2] = 0; //R
    //        rgb[b + i + 3] = 0; //A
    //    }
    //}

    SDL_UpdateTexture(sdl_texture, NULL, rgb, sdl_width * pixsel_size);  
    SDL_RenderClear(sdl_render);
    SDL_Rect sdl_rect;
    sdl_rect.x = 0;
    sdl_rect.y = 0;
    sdl_rect.w = sdl_width;
    sdl_rect.h = sdl_height;
    SDL_RenderCopy(sdl_render, sdl_texture, NULL, &sdl_rect);
    SDL_RenderPresent(sdl_render);
}

其中Qt窗口的创建,可以使用Qtcreater打开.ui文件内来创建,右上角为类的类型与类名,左下角的为该类的属性配置

QT配合SDL渲染一幅图像

上一篇:QWidget派生的子类对样式表不起作用,而Qt自带的库却没问题


下一篇:Qt窗口样式表不生效的问题