J'essaie de créer un canevas de dessin SDL à l'intérieur d'une fenêtre QT4 simple, en suivant les informations fournies in the SDL wiki et dans une autre question sur ce site . Le projet est un émulateur NES utilisant QT et SDL qu'un ami et moi avons décidé d'essayer de créer.Essayer de créer un widget SDL dans QT4 en utilisant SDL_WINDOWID, mais impossible d'afficher le widget
Actuellement, j'ai une classe main_window qui contiendra le widget SDL, les menus que j'ai mis en place, et probablement d'autres choses au fur et à mesure que le projet se développe. Le widget SDL que je crée s'appelle rom_canvas et hérite de QWidget. Jusqu'à présent, je suis capable de définir la variable d'environnement SDL_WINDOWID et il me semble pouvoir interagir avec le widget en ce que je peux définir et obtenir sa géométrie et voir qu'elle est en fait "visible", mais rien n'apparaît réellement dans la fenêtre.
Je n'ai aucune expérience avec QT4 et SDL jusqu'à présent et je n'ai pas beaucoup d'expérience en C++, donc je pourrais manquer quelque chose d'évident.
est ici la classe 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);
}
Et voici le constructeur 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();
}
Le code est un peu en désordre depuis que j'ai essayé des choses pour que cela fonctionne. Toute aide est bien sûr grandement appréciée.
Si vous n'avez pas beaucoup d'expérience en Qt ou SDL, je reviendrai en utilisant les deux. Vous pouvez probablement accomplir ce que vous voulez en utilisant seulement l'un des deux. – thekidder
Je doute que, puisque SDL n'est pas une bibliothèque GUI. Son problème est très intéressant et j'ai eu l'exemple du problème avec Gtkmm. J'ai fini par utiliser Cairo pour dessiner librement dans un Widget. – piotr