将SDL2渲染为QWidget

SDL2 Rendering into QWidget

本文关键字:QWidget SDL2      更新时间:2023-10-16

我希望将我在GTK2和SDL1.2中编写的模拟器移植到使用QT5和SDL2.0.3。到目前为止,只要模拟器都在SDL2中独立工作,GUI在QT中工作得很好,它们都是相互作用的。我的问题是试图让SDL2出现在QWidget中。在SDL1.2中使用窗口破解方法可以很好地工作。

从我在网上读到的一切,这可以与SDL_CreateWindowFrom函数从QT小部件获得winId()并将其传递给它。然而,这似乎是为当你使用openGL。

我想知道的是如何做到这一点,当我只使用SDL2的标准绘图功能的纹理,没有OpenGL。到目前为止,我所有的尝试都失败了,SDL根本没有出现在小部件中。

或者,我知道您可以将sdl_surface转换为QImage。我该如何让QT小部件在每次QImage更新时更新(60fps)呢?复杂的是QT和SDL运行在不同的线程中。

如果有人有一个方向指向我的一些想法或一些有用的例子代码,可能会导致一个答案,我将是非常伟大的。我还没有提供代码,因为我还不确定如何做到这一点,提供任何代码。

EDIT

因此,在使用SDL和QT进行了一些试验之后,我已经设法让SDL2使用其标准绘图工具绘制到QWidget中。然而,这只适用于将渲染器设置为SDL_RENDERER_SOFTWARE时。如果我尝试使用SDL_RENDERER_ACCELERATED,我也会喜欢。它导致QT窗口完全锁定,无法绘制任何东西(包括窗口中的所有其他小部件),最后由于操作系统(在我的测试案例中是Kubuntu)没有响应而终止。

有人知道为什么会这样吗?当SDL2绘制到自己的SDL_CreateWindowSDL_CreateRenderer创建的窗口时,我可以使用SDL_RENDERER_ACCELERATED。只有在绘制到QWidget时才会出现问题。

这是我到目前为止的代码:

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()方法,使其在屏幕上绘制自己