Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Desplay error when using SDL2 to draw a Qt widget



  • Recently, I am going to create a game editor for my game written by SDL2.
    I search around about how to mix SDL2 with Qt.
    Finally, I got it run successfully but with a strange display error:

    Error Window Picture

    Here are three code files: main.cpp, widget.cpp, widget.h.
    widget.h

    #ifndef WIDGET_H
    #define WIDGET_H
    
    #include <SDL2/SDL.h>
    #include <SDL2/SDL_image.h>
    #include <QWidget>
    #include <QPaintEvent>
    class SDL2Widget : public QWidget
    {
        Q_OBJECT
    public:
        SDL2Widget(QWidget* parent=0);
        ~SDL2Widget();
    protected:
        void paintEvent(QPaintEvent* event);
    
    private:
        SDL_Window *window;
        SDL_Renderer *render;
        SDL_Surface *surface;
        SDL_Texture *texture;
    };
    
    #endif // WIDGET_H
    

    widget.cpp

    #include "widget.h"
    
    SDL2Widget::SDL2Widget(QWidget* parent) : QWidget(parent) {
      /* SDL2 */
      SDL_Init(SDL_INIT_EVERYTHING);
      /* Create SDL_Window from QWidget by using its winid */
      window = SDL_CreateWindowFrom((void*)this->winId());
      /* Init SDL2 Image */
      IMG_Init(IMG_INIT_JPG);
      /* load picture and create a SDL surface */
      surface = IMG_Load("demo.jpg");
    
      /* Creat a SDL2 render from SDL window*/
      render = SDL_CreateRenderer(
          window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
    }
    
    SDL2Widget::~SDL2Widget() {
      SDL_DestroyTexture(texture);
      SDL_DestroyRenderer(render);
    }
    
    /* Put SDL render staff in paintEvent */
    void SDL2Widget::paintEvent(QPaintEvent* event) {
      /* Create a texture */
      texture = SDL_CreateTextureFromSurface(render, surface);
      /* Clear render content*/
      SDL_RenderClear(render);
      /* Copy texture to render */
      SDL_RenderCopy(render, texture, NULL, NULL);
      /* Render on window */
      SDL_RenderPresent(render);
    }
    

    main.cpp

    #include <QApplication>
    #include <QLayout>
    #include <QPushButton>
    
    #include "widget.h"
    
    int main(int argc, char* argv[]) {
      QApplication app(argc, argv);
      QBoxLayout* layout = new QBoxLayout(QBoxLayout::TopToBottom);
      SDL2Widget* sdlWidget = new SDL2Widget();
      QPushButton* button = new QPushButton("Button");
      layout->addWidget(sdlWidget);
      layout->addWidget(button);
    
      QWidget w;
      w.setLayout(layout);
    
      w.show();
      w.resize(640, 400);
    
      return app.exec();
    }
    
    

    I guess it may be a thread problem?



  • Finally, I give up using SDL to render on a QT Widget.
    Instead, I choose to create a QtWindow from a window created by SDL by using QWindow::fromWinId(WId id).
    Under windows, the window handle: HWND of an SDL window can be obtained from the SDL_SysWMinfo.win.window.

    And to avoid thread problems. The SDL window should be inited and created in a std::thread before the QApplication a(argc, argv);


Log in to reply