Desplay error when using SDL2 to draw a Qt widget
Solved
General and Desktop
-
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: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 usingQWindow::fromWinId(WId id)
.
Under windows, the window handle:HWND
of an SDL window can be obtained from theSDL_SysWMinfo.win.window
.And to avoid thread problems. The SDL window should be inited and created in a
std::thread
before theQApplication a(argc, argv)
;