Hallo Welt
Beim Versuch, SFML in ein QFrame einzubetten (Weil Qt sich standhaft weigert, teils als Thread, teils integriert zu laufen), bin ich zu einem Punkt gekommen, wo ich schlicht nicht mehr weiter weiss.
Gemäss der offiziellen Dokumentation (die allerdings uralt ist und daher einige Anpassungen benötigte), habe ich die Klassen gekapselt und mit Vererbung das SFML-Fenster hin- und hergeschoben.
Soweit, so gut. Doch nun: Sämtliche events (trotz StrongFocus) werden im SFML-Fenster einfach ignoriert. Zudem führt ein resizen des Fensters zu einem netten kleinen Crash, der insofern ärgerlich ist, da der Fehler in der Qt-DLL auftritt, ich also weder Funktionsname noch sonstwas erkennen kann.
Ein bisschen Code (auf die meiner Meinung nach wichtigen Bereiche gekürzt):
Und dann noch die main:
Ich sitze nun schon einige Tage daran und bin kurz davor, Qt von meiner Platte zu fegen...
Hätte vielleicht einer die Güte, mich zu erleuchten?
Gruss
cwriter
/EDIT:
Den Crash habe ich beheben können (undefined pointer usw.), die Eventweiterleitung jedoch nicht. Irgendeine Idee dazu?
Beim Versuch, SFML in ein QFrame einzubetten (Weil Qt sich standhaft weigert, teils als Thread, teils integriert zu laufen), bin ich zu einem Punkt gekommen, wo ich schlicht nicht mehr weiter weiss.
Gemäss der offiziellen Dokumentation (die allerdings uralt ist und daher einige Anpassungen benötigte), habe ich die Klassen gekapselt und mit Vererbung das SFML-Fenster hin- und hergeschoben.
Soweit, so gut. Doch nun: Sämtliche events (trotz StrongFocus) werden im SFML-Fenster einfach ignoriert. Zudem führt ein resizen des Fensters zu einem netten kleinen Crash, der insofern ärgerlich ist, da der Fehler in der Qt-DLL auftritt, ich also weder Funktionsname noch sonstwas erkennen kann.
Ein bisschen Code (auf die meiner Meinung nach wichtigen Bereiche gekürzt):
C++:
class QSFMLCanvas : public QWidget, public sf::RenderWindow
{
public :
explicit QSFMLCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size, unsigned int FrameTime = 0);
virtual ~QSFMLCanvas(){};
private :
virtual void OnInit(){};
virtual void OnUpdate(){};
virtual QPaintEngine* paintEngine() const;
virtual void showEvent(QShowEvent*);
virtual void paintEvent(QPaintEvent*);
QTimer myTimer;
bool myInitialized;
};
class MyCanvas : public QSFMLCanvas
{
public :
MyCanvas(QWidget* Parent, const QPoint& Position, const QSize& Size) :
QSFMLCanvas(Parent, Position, Size)
{
this->window = NULL;
}
void OnInit();
void OnUpdate();
void resizeEvent(QResizeEvent* event);
//void paintEvent(QPaintEvent*);
public slots:
void resized(sf::Vector2i r);
private :
sf::RectangleShape mark;
DLLLoader loader;
sf::Clock cl;
page pagesprite;
double zoom;
sf::View view;
int Progress;
bool mousePressed;
sf::Vector2i oldpos;
QWidget* mainw;
sf::Vector2f oldMousePos;
Textures textures;
QMenu* menu;
sf::RenderWindow* window;
};
C++:
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+1);
myTimer.setSingleShot(false);
}
void QSFMLCanvas::showEvent(QShowEvent*)
{
if (!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
#ifdef Q_WS_X11
XFlush(QX11Info::display());
#endif
// Create the SFML window with the widget handle
this->sf::RenderWindow::create((HWND)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.setSingleShot(false);
myTimer.start();
myInitialized = true;
}
}
QPaintEngine* QSFMLCanvas::paintEngine() const
{
return 0;
}
void QSFMLCanvas::paintEvent(QPaintEvent*)
{
// Let the derived class do its specific stuff
//HIER IST DER CRASH (OnUpdate())<---------------------------------------------------------
OnUpdate();
// Display on screen
this->sf::RenderWindow::display();
//draw
}
void MyCanvas::OnInit()
{
window = static_cast<sf::RenderWindow*>(this);
printf("Initializing...\n");
textures.load("images.list");
zoom = 1.0;
view.setViewport(sf::FloatRect(0,0,640,480));
view.setCenter(1050,0);
sf::RenderWindow::setView(view);
sf::RenderWindow::setActive();
bool running = true;
oldpos.x = 0;
oldpos.y = 0;
pagesprite.attachTextures(&textures);
pagesprite.addLine(200,200,1900,2);
for(size_t i = 0; i < ns->size(); i++)
{
pagesprite.add((*ns)[i]);
}
pagesprite.update();
//Dieser Bereich funktioniert. (Funktionierte schon immer)
}
void MyCanvas::OnUpdate()
{
if(window->isOpen())
{
cl.restart();
sf::Event event;
while (window->pollEvent(event))
{
//In diese Schlaufe wird gar nie gesprungen
// Close window: exit
if (event.type == sf::Event::Closed)
window->close();
// Resize event: adjust the viewport
else if (event.type == sf::Event::Resized)
{
view.setSize(event.size.width,event.size.height);
window->setView(view);
}
else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Return))
{
}
else if(event.type == sf::Event::MouseWheelMoved)
{
zoom += double(event.mouseWheel.delta/10.0f);
printf("%f\n",zoom);
}
}
window->clear(sf::Color(50,50,50));
pagesprite.draw(window);
window->draw(mark);
window->setView(view);
view.zoom(zoom);
zoom = 1.0;
}
}
void MyCanvas::resizeEvent(QResizeEvent* event) //Versuch einer Reimplementierung: Crash. (derselbe)
{
QWidget::resizeEvent(event);
if(window != NULL)
{
window->setSize(sf::Vector2u(width(), height()));
window->setView(view);
}
}
Und dann noch die main:
C++:
int main(int argc, char* argv[])
{
QApplication app(argc,argv);
QFrame* MainFrame = new QFrame;
MainFrame->setWindowTitle("Qt SFML");
MainFrame->resize(400, 400);
// Create a SFML view inside the main frame
MyCanvas* SFMLView = new MyCanvas(MainFrame, QPoint(0, 0), QSize(1024, 1024));
QVBoxLayout* lay = new QVBoxLayout();
lay->addWidget(SFMLView);
MainFrame->setLayout(lay);
MainFrame->show();
SFMLView->show();
app.exec();
//Aufräumen usw.
return 0;
}
Ich sitze nun schon einige Tage daran und bin kurz davor, Qt von meiner Platte zu fegen...
Hätte vielleicht einer die Güte, mich zu erleuchten?
Gruss
cwriter
/EDIT:
Den Crash habe ich beheben können (undefined pointer usw.), die Eventweiterleitung jedoch nicht. Irgendeine Idee dazu?
Zuletzt bearbeitet: