简体   繁体   中英

SDL2 Rendering into QWidget

I'm looking to port an emulator I wrote in GTK2 and SDL1.2 into using QT5 and SDL2.0.3. So far thats been fine as far as the emulator all works in SDL2 independantly and the GUI works fine in QT, with them both interacting. My issue is with trying to get SDL2 to appear inside a QWidget. This is something that worked fine in SDL1.2 using the window hack method.

From everything I've read online, this can be down with the SDL_CreateWindowFrom function getting the winId() from a QT Widget and passing it into it. However this seems to be for when you are using openGL.

What I want to know is how to do this when im only using SDL2's standard drawing functions to a texture, no OpenGL. All my attempts so far have failed and SDL just didn't appear in the widget at all.

Alternatively, I know you can convert an SDL_Suface to a QImage. How would I then go about getting the QT Widget to update everytime the QImage is updated (60fps). The complication with this is QT and SDL are running in seperate threads.

If anyone has some idea of a direction to point me or some useful example codes that may lead to an answer I would be very greatful. I havn't provided code because I'm not yet sure how to do it, to provide any code.

EDIT

So after some trialing with SDL and QT. I have managed to get SDL2 to draw into a QWidget using the its Standard Drawing tools. However this only works when setting the renderer to SDL_RENDERER_SOFTWARE . If i try and use SDL_RENDERER_ACCELERATED like I would perfer too. It results in the QT window locking up completely and failing to draw anything (including all other widgets in the window), and finally being terminated as not responding by the operating system (Kubuntu in my testing case).

Does any one have any leads as to why this may be. I can use SDL_RENDERER_ACCELERATED fine when SDL2 is drawing into its own window created with SDL_CreateWindow and SDL_CreateRenderer . Its only a problem when drawing to a QWidget.

Here is the code I have so far:

main.cpp

#include "mainwindow.h"
#include <QApplication>
#include <SDL2/SDL.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    SDL_Init(SDL_INIT_VIDEO);
    SDL_Window* window = SDL_CreateWindowFrom((void*)w.ptr_gfx->winId());
    SDL_Renderer* render = SDL_CreateRenderer(window, -1, SDL_RENDERER_SOFTWARE);

    SDL_SetRenderDrawColor(render, 255, 0, 0, 255);
    SDL_RenderFillRect(render, NULL);
    SDL_RenderPresent(render);

    return a.exec();

    SDL_DestroyWindow(window);
    SDL_DestroyRenderer(render);
    SDL_Quit();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    ptr_gfx = ui->gfx;
    ui->gfx->setUpdatesEnabled(false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    Ui::MainWindow *ui;
    QWidget* ptr_gfx;
};

#endif // MAINWINDOW_H

mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <widget class="QWidget" name="gfx" native="true">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>10</y>
      <width>191</width>
      <height>131</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>20</height>
    </rect>
   </property>
  </widget>
  <widget class="QToolBar" name="mainToolBar">
   <attribute name="toolBarArea">
    <enum>TopToolBarArea</enum>
   </attribute>
   <attribute name="toolBarBreak">
    <bool>false</bool>
   </attribute>
  </widget>
  <widget class="QStatusBar" name="statusBar"/>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

使用新数据更新QImage ,只需调用窗口小部件的repaint()方法,使其在屏幕上绘制自己。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM