SFMLWidget.hpp#include <SFML/Graphics/RenderWindow.hpp>
#include <SFML/Graphics/CircleShape.hpp>
#include <QWidget>
class SFMLWidget : public QWidget
{
public:
SFMLWidget(QWidget* parent = nullptr);
void handleEvents();
void update();
void draw();
private:
QPaintEngine *paintEngine() const;
void enterEvent(QEvent *event) override;
void paintEvent(QPaintEvent *event) override;
void resizeEvent(QResizeEvent *event) override;
sf::RenderWindow m_window;
sf::View m_view;
sf::CircleShape m_circle;
};
SFMLWidget.cpp#include "SFMLWidget.hpp"
#ifdef Q_WS_X11
#include <Qt/qx11info_x11.h>
#include <X11/Xlib.h>
#endif
#include <QResizeEvent>
#include <SFML/Window/Event.hpp>
#include <iostream>
SFMLWidget::SFMLWidget(QWidget *parent) :
QWidget(parent),
m_circle(100)
{
//Setup some states to allow direct rendering into the widget.
setAttribute(Qt::WA_PaintOnScreen);
setAttribute(Qt::WA_OpaquePaintEvent);
setAttribute(Qt::WA_NoSystemBackground);
setAttribute(Qt::WA_PaintUnclipped);
//Set strong focus to enable keyboard events to be received.
setFocusPolicy(Qt::StrongFocus);
//Under X11, we need to flush the commands sent to the server to ensure that
//SFML will get an updated view of the windows
#ifdef Q_WS_X11
XFlush(QX11Info::display());
#endif
// Create the SFML window with the Qt widget handle
m_window.create(reinterpret_cast<sf::WindowHandle>(winId()));
//m_window.setFramerateLimit(60);
m_circle.setFillColor(sf::Color::Red);
}
QPaintEngine* SFMLWidget::paintEngine() const
{
//We make the paintEvent function return a null paint engine. This functions works together with
//the WA_PaintOnScreen flag to tell Qt that we're not using any of its built-in paint engines.
return nullptr;
}
void SFMLWidget::enterEvent(QEvent *)
{
setFocus();
}
void SFMLWidget::paintEvent(QPaintEvent *)
{
draw();
}
void SFMLWidget::resizeEvent(QResizeEvent *event)
{
// update the view to the new size of the window
sf::FloatRect visibleArea(0.f, 0.f, event->size().width(), event->size().height());
m_window.setView(sf::View(visibleArea));
}
void SFMLWidget::handleEvents()
{
// check all the windows events
sf::Event event;
while (m_window.pollEvent(event))
{
// "close requested" event: we close the window
if (event.type == sf::Event::Closed)
m_window.close();
else if (event.type == sf::Event::Resized)
{
// update the view to the new size of the window
sf::FloatRect visibleArea(0.f, 0.f, event.size.width, event.size.height);
m_window.setView(sf::View(visibleArea));
}
else if (event.type == sf::Event::KeyReleased)
{
// close if escape key was pressed
if (event.key.code == sf::Keyboard::Escape)
{
m_window.close();
}
else if (event.key.code == sf::Keyboard::Space)
{
m_circle.setFillColor(sf::Color::Green);
}
}
else if (event.type == sf::Event::MouseWheelScrolled)
{
if (event.mouseWheelScroll.wheel == sf::Mouse::VerticalWheel)
{
std::cout << "They see me scrolling: " << event.mouseWheelScroll.delta << std::endl;
}
}
else if (event.type == sf::Event::MouseButtonReleased)
{
std::cout << "Mouse was clicked!" << std::endl;
}
}
}
void SFMLWidget::update()
{
// update all the things
}
void SFMLWidget::draw()
{
// clear the window to dark grey
m_window.clear(sf::Color(50, 50, 50));
// draw the circle
m_window.draw(m_circle);
// display the windows content
m_window.display();
}
MainWindow.hpp#include "SFMLWidget.hpp"
#include <QMainWindow>
#include <QPushButton>
class MainWindow : public QMainWindow
{
//Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
SFMLWidget& getSFMLWidget();
private:
SFMLWidget m_sfmlWidget;
QPushButton* m_wowButton;
private slots:
void handleButton();
};
MainWindow.cpp#include <QBoxLayout>
#include <QFormLayout>
#include <QGroupBox>
#include <QLabel>
#include <QLineEdit>
#include <QComboBox>
#include <QSpinBox>
#include <QMessageBox>
#include "MainWindow.hpp"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
setWindowTitle("Qt SFML example!");
m_sfmlWidget.setMinimumSize(400, 400);
QGroupBox* controlsGroupBox = new QGroupBox("UI Foo");
controlsGroupBox->setMaximumWidth(200);
QFormLayout *controlsLayout = new QFormLayout;
m_wowButton = new QPushButton("Such Button!");
connect(m_wowButton, SIGNAL (released()), this, SLOT (handleButton()));
controlsLayout->addRow(m_wowButton);
controlsGroupBox->setLayout(controlsLayout);
QHBoxLayout* mainLayout = new QHBoxLayout();
mainLayout->addWidget(&m_sfmlWidget);
mainLayout->addWidget(controlsGroupBox);
QWidget *widget = new QWidget;
widget->setLayout(mainLayout);
setCentralWidget(widget);
}
SFMLWidget &MainWindow::getSFMLWidget()
{
return m_sfmlWidget;
}
void MainWindow::handleButton()
{
QMessageBox msgBox;
msgBox.setText("Much wow!");
msgBox.exec();
}
main.cpp#include "MainWindow.hpp"
#include "SFMLWidget.hpp"
#include <SFML/System/Sleep.hpp>
#include <QApplication>
int main(int argv, char* args[])
{
QApplication app(argv, args);
MainWindow mainWindow;
mainWindow.show();
SFMLWidget& sfmlWidget = mainWindow.getSFMLWidget();
while (mainWindow.isVisible())
{
sfmlWidget.handleEvents();
sfmlWidget.update();
sfmlWidget.draw();
app.processEvents();
sf::sleep(sf::seconds(1.f / 60.f));
}
app.exit();
return 0;
}
Output: