【问题标题】:SDL2 Rendering into QWidgetSDL2 渲染到 QWidget
【发布时间】:2014-08-10 20:34:58
【问题描述】:

我希望将我在 GTK2 和 SDL1.2 中编写的模拟器移植到使用 QT5 和 SDL2.0.3。到目前为止,模拟器都可以在 SDL2 中独立工作,而 GUI 在 QT 中可以正常工作,它们都可以交互。我的问题是试图让 SDL2 出现在 QWidget 中。这在 SDL1.2 中使用 window hack 方法运行良好。

根据我在网上阅读的所有内容,这可以通过 SDL_CreateWindowFrom 函数从 QT Widget 获取 winId() 并将其传递给它来解决。但是,这似乎适用于您使用 openGL 时。

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

另外,我知道您可以将 SDL_Suface 转换为 QImage。每次更新 QImage (60fps) 时,我将如何让 QT Widget 更新。这样做的复杂性是 QT 和 SDL 在单独的线程中运行。

如果有人对指向我的方向有一些想法或一些有用的示例代码可能会导致答案,我会非常感激。我还没有提供代码,因为我还不确定如何提供任何代码。

EDIT

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

有没有人知道为什么会这样。当 SDL2 绘制到使用SDL_CreateWindow 和SDL_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();
}

主窗口.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;
}

主窗口.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

主窗口.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>

【问题讨论】:

  • 嗨,我玩游戏迟到了。你解决问题了吗?谢谢

标签: c++ qt qwidget sdl-2


【解决方案1】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-05-03
    • 2014-01-14
    相关资源
    最近更新 更多