So I've actually tried the 1.6 tutorial. I wasn't aware that you couldn't launch an SFML Window out of nowhere when you're already using Qt.
QSFMLCanvas.hpp#pragma once
#include <QTimer>
#include <QWidget>
#include <SFML/Graphics.hpp>
class QSFMLCanvas : public QWidget, public sf::RenderWindow
{
private:
QTimer myTimer;
bool myInitialized;
public:
explicit QSFMLCanvas(QWidget*, const QPoint&, const QSize&, unsigned int = 0);
QSFMLCanvas(void);
virtual ~QSFMLCanvas(void);
virtual void showEvent(QShowEvent*);
virtual QPaintEngine* paintEngine(void) const;
virtual void paintEvent(QPaintEvent*);
virtual void OnInit(void);
virtual void OnUpdate(void);
};
QSFMLCanvas.cpp (not using X11... I mean, if I were using this, I would know right?)
#include <iostream>
#include "QSFMLCanvas.hpp"
QSFMLCanvas::QSFMLCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size, unsigned int FrameTime) :
QWidget(Parent),
myInitialized (false)
{
// Setup some states to allow direct rendering into the widget
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_NoSystemBackground);
// Set strong focus to enable keyboard events to be received
setFocusPolicy(Qt::StrongFocus);
// Setup the widget geometry
move(Position);
resize(Size);
// Setup the timer
myTimer.setInterval(FrameTime);
}
QSFMLCanvas::QSFMLCanvas(void)
{
}
QSFMLCanvas::~QSFMLCanvas(void)
{
}
void QSFMLCanvas::showEvent(QShowEvent*)
{
if (not myInitialized)
{
// Under X11, we need to flush the commands sent to the server to ensure that
// SFML will get an updated view of the windows
//XFlush(QX11Info::display());
// Create the SFML window with the widget handle
RenderWindow::create(static_cast<sf::WindowHandle>(winId()));
// Let the derived class do its specific stuff
OnInit();
// Setup the timer to trigger a refresh at specified framerate
connect(&myTimer, SIGNAL(timeout()), this, SLOT(repaint()));
myTimer.start();
myInitialized = true;
}
}
QPaintEngine* QSFMLCanvas::paintEngine(void) const
{
return 0;
}
void QSFMLCanvas::paintEvent(QPaintEvent*)
{
// Let the derived class do its specific stuff
OnUpdate();
// Display on screen
RenderWindow::display();
}
void QSFMLCanvas::OnInit(void)
{
}
void QSFMLCanvas::OnUpdate(void)
{
}
MyCanvas.hpp#pragma once
#include <SFML/Graphics.hpp>
#include "QSFMLCanvas.hpp"
class MyCanvas : public QSFMLCanvas
{
private:
sf::Clock myClock;
sf::Texture myImage;
sf::Sprite mySprite;
public:
MyCanvas(QWidget*, const QPoint&, const QSize&);
MyCanvas(void);
~MyCanvas(void);
void OnInit(void);
void OnUpdate(void);
};
MyCanvas.cpp#include <iostream>
#include <QDir>
#include <string>
#include "MyCanvas.hpp"
MyCanvas::MyCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size) : QSFMLCanvas(Parent, Position, Size)
{
}
MyCanvas::MyCanvas(void)
{
}
MyCanvas::~MyCanvas(void)
{
}
void MyCanvas::OnInit(void)
{
// Load the image
std::cout << "onInit" << std::endl;
QString dir = QDir::currentPath();
std::string utf8_text = dir.toUtf8().constData();
std::cout << "HELLO: " << utf8_text << std::endl;
if (not myImage.loadFromFile(utf8_text + "/chef.png"))
std::cout << "Loading error"<< std::endl;
else
std::cout << "Image was loaded fine" << std::endl;
// Setup the sprite
mySprite.setTexture(myImage);
mySprite.setPosition(150, 150);
std::cout << "setting the texture of the sprite" << std::endl;
//mySprite.setCenter(mySprite.GetSize() / 2.f);
myClock.restart();
}
void MyCanvas::OnUpdate(void)
{
// Clear screen
RenderWindow::clear(sf::Color(0, 128, 0));
// Rotate the sprite
mySprite.rotate(myClock.getElapsedTime().asSeconds() * 100.f);
// Draw it
RenderWindow::draw(mySprite);
myClock.restart();
}
The QFrame and MyCanvas instances are defined as public static std::shared_ptr of some class:
class WindowFrame : public QObject
{
Q_OBJECT
// ...
public:
static std::shared_ptr<QFrame> SFMLFrame;
static std::shared_ptr<MyCanvas> SFMLWindow;
WindowFrame(void);
~WindowFrame(void);
// ...
};
Now, here's what my main function looks like:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
WindowFrame::SFMLFrame = std::make_shared<QFrame>();
WindowFrame::SFMLFrame->setWindowTitle("Qt SFML");
WindowFrame::SFMLFrame->resize(GS::resWidth, GS::resHeight);
WindowFrame::SFMLFrame->show();
WindowFrame::SFMLWindow = std::make_shared<MyCanvas>(WindowFrame::SFMLFrame.get(), QPoint(0, 0), QSize(GS::resWidth, GS::resHeight));
WindowFrame::SFMLFrame->show();
// stuff irrelevant to SFML
return app.exec();
}
But I still have the same problem as before... The following line is stalled indefinitely, when I press a QPushButton that causes its execution:
WindowFrame::SFMLWindow->sf::RenderWindow::create(sf::VideoMode(GS::resWidth, GS::resHeight), "Some Window :D");
So, what am I doing wrong in all this? Is there nothing too redundant in doing:
WindowFrame::SFMLFrame->resize(GS::resWidth, GS::resHeight);
// ...
WindowFrame::SFMLWindow = std::make_shared<MyCanvas>(WindowFrame::SFMLFrame.get(), QPoint(0, 0), QSize(GS::resWidth, GS::resHeight));
Thank you in advance.