SDL2如何渲染到QWidget?

6
我想将我写的GTK2和SDL1.2模拟器移植到使用QT5和SDL2.0.3。到目前为止��模拟器在SDL2中独立运行得很好,GUI在QT中也很好地工作,并且二者可以交互。我的问题是如何让SDL2出现在QWidget中。这是在SDL1.2中使用window hack方法很好用的功能。
根据我在线上看到的所有信息,这可以通过从QT Widget中获取winId()并将其传递给SDL_CreateWindowFrom函数来完成。但是,这似乎只适用于使用openGL的情况。
我想知道的是当我只使用SDL2的标准绘图函数绘制纹理时,该如何做。我迄今为止的尝试都失败了,SDL根本没有出现在widget中。
或者,我知道可以将SDL_Surface转换为QImage。然后,我该如何在每次更新QImage时(60fps)使QT Widget更新?这样做的麻烦之处在于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>

嗨,我来晚了。你解决问题了吗?谢谢。 - Nicholas Humphrey
1个回答

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接