gpt4 book ai didi

c++ - 尝试使用 SDL_WINDOWID 在 QT4 中制作 SDL 小部件,但无法显示小部件

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:12:29 27 4
gpt4 key购买 nike

我正在尝试根据提供的信息在一个简单的 QT4 窗口内创建一个 SDL 绘图 Canvas in the SDL wiki以及本网站的另一个问题。该项目是一个使用 QT 和 SDL 的 NES 模拟器,我和一个 friend 决定尝试创建它。

目前,我有一个 main_window 类,它将包含 SDL 小部件、我设置的菜单,以及项目开发时可能包含的其他内容。我正在创建的 SDL 小部件称为 rom_canvas 并继承自 QWidget。到目前为止,我能够设置 SDL_WINDOWID 环境变量并且我似乎能够与小部件进行交互,因为我可以设置并获取它的几何形状并看到它实际上是“可见的”,但实际上没有显示在 window 。

到目前为止,我对 QT4 和 SDL 没有任何经验,也没有大量的 C++ 经验,所以我可能会遗漏一些明显的东西。

这是 rom_canvas 类:

#include "rom_canvas.hpp"
#include <iostream>
#include <cstdlib>
#include <QString>

rom_canvas::rom_canvas(QWidget *parent)
: QWidget(parent)
{
parent->setAttribute(Qt::WA_PaintOnScreen);
parent->setAttribute(Qt::WA_OpaquePaintEvent);
// setAttribute(Qt::WA_PaintOnScreen);
// setAttribute(Qt::WA_OpaquePaintEvent);

setUpdatesEnabled(false);

// a hack I found online to get the SDL surface to appear in our own window
QString id;
id.setNum(parent->winId());
setenv("SDL_WINDOWID", id.toAscii().data(), 1);
SDL_InitSubSystem(SDL_INIT_VIDEO);

resize(320, 240);

// change constants later
sdl_screen = SDL_SetVideoMode(320, 240, DEFAULT_BPP, SDL_SWSURFACE);

if(!sdl_screen)
std::cout << "couldn't create screen" << std::endl;

SDL_LockSurface(sdl_screen);
SDL_FillRect(sdl_screen, NULL, 0x00FF0000);
SDL_UnlockSurface(sdl_screen);
SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
}

rom_canvas::~rom_canvas()
{
// do NOT release sdl_screen here; that's done when SDL_Quit() is called in main().
}

// this method is a protected slot
void rom_canvas::test()
{
std::cout << "rom_canvas test" << std::endl;
SDL_LockSurface(sdl_screen);
SDL_FillRect(sdl_screen, NULL, 0x00FF0000);
SDL_UnlockSurface(sdl_screen);
SDL_UpdateRect(sdl_screen, 0, 0, 0, 0);
}

这是 main_window 的构造函数:

main_window::main_window(QWidget *parent)
: QMainWindow(parent)
{
canvas = new rom_canvas(this);
setCentralWidget(canvas);
canvas->setGeometry(100, 100, 100, 100);
canvas->show();
canvas->update();

// Add File Menu
open_action = new QAction(tr("&Open..."), this);
open_action->setShortcuts(QKeySequence::Open);
open_action->setStatusTip(tr("Open a new ROM"));
connect(open_action, SIGNAL(triggered()), this, SLOT(select_rom()));

exit_action = new QAction(tr("E&xit"), this);
exit_action->setStatusTip(tr("Exit nesT"));
connect(exit_action, SIGNAL(triggered()), /*QApplication::instance()*/canvas, SLOT(/*quit()*/test()));
// Remember to change this back!!

file_menu = menuBar()->addMenu(tr("&File"));
file_menu->addAction(open_action);
file_menu->addAction(exit_action);

rom_dir = QDir::homePath();
}

代码有点乱,因为我一直在尝试让它工作。任何帮助当然非常感谢。

最佳答案

我想您已经知道,但 SDL_WINDOWID 技巧可能不可移植 - 我很确定它在 Mac 上不起作用。我很好奇你想要 SDL 做什么,在这种情况下 - 如果你只是想要一个像素可寻址的图像缓冲区(或几个),请使用 QPixmap/QImage 并坚持使用纯 Qt。或者,如果您想要 SDL sprite 功能,我建议将 SDL 合成到附加到 QImage 的内存缓冲区,然后将其绘制到 Qt 小部件。 (或者使用 QImages 作为 Sprite ,并使用 OpenGL QPainter 后端)

在内部,Qt 非常努力地使用平台本地代码来进行图像格式转换,因此尽管这听起来相当繁重,但我认为它会足够快,并且比 SDL_WINDOWID 技巧更健壮和可移植。

关于c++ - 尝试使用 SDL_WINDOWID 在 QT4 中制作 SDL 小部件,但无法显示小部件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1469815/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com