简体   繁体   English

SDL2渲染到QWidget

[英]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. 我希望将我在GTK2和SDL1.2中编写的模拟器移植到使用QT5和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. 到目前为止,只要模拟器在SDL2中独立工作并且GUI在QT中工作正常,它们都可以互动。 My issue is with trying to get SDL2 to appear inside a QWidget. 我的问题是尝试让SDL2出现在QWidget中。 This is something that worked fine in SDL1.2 using the window hack method. 这是使用窗口黑客方法在SDL1.2中正常工作的东西。

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. 从我在线阅读的所有内容中,可以通过SDL_CreateWindowFrom函数从QT Widget获取winId()并将其传递给它。 However this seems to be for when you are using openGL. 但是,这似乎适用于使用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. 我想知道的是当我只使用SDL2的标准绘图功能到纹理,没有OpenGL时如何做到这一点。 All my attempts so far have failed and SDL just didn't appear in the widget at all. 到目前为止,我所有的尝试都失败了,SDL根本没有出现在小部件中。

Alternatively, I know you can convert an SDL_Suface to a QImage. 或者,我知道您可以将SDL_Suface转换为QImage。 How would I then go about getting the QT Widget to update everytime the QImage is updated (60fps). 每当QImage更新(60fps)时,我将如何让QT Widget更新。 The complication with this is QT and SDL are running in seperate threads. 与此相关的复杂因素是QT和SDL在单独的线程中运行。

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. 经过一些SDL和QT的试验。 I have managed to get SDL2 to draw into a QWidget using the its Standard Drawing tools. 我已经设法使用标准绘图工具将SDL2绘制到QWidget中。 However this only works when setting the renderer to SDL_RENDERER_SOFTWARE . 但是,这仅在将渲染器设置为SDL_RENDERER_SOFTWARE If i try and use SDL_RENDERER_ACCELERATED like I would perfer too. 如果我尝试使用SDL_RENDERER_ACCELERATED ,我也SDL_RENDERER_ACCELERATED 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). 它导致QT窗口完全锁定并且无法绘制任何内容(包括窗口中的所有其他小部件),并最终因操作系统没有响应而终止(在我的测试用例中为Kubuntu)。

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 . 我可以用SDL_RENDERER_ACCELERATED罚款时,SDL2是借鉴与创造它自己的窗口SDL_CreateWindowSDL_CreateRenderer Its only a problem when drawing to a QWidget. 绘制到QWidget时它只是一个问题。

Here is the code I have so far: 这是我到目前为止的代码:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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