如何在 SFML 中使用 wxWidgets?
How to use wxWidgets with SFML?
我正在做一系列关于物理模拟的应用程序,直到现在我已经完成了其中一些纯粹使用方便的 SFML 库。现在我想给它们添加一些 GUI 元素。我对 wxWidgets 框架和 wxFrames 只是有点熟悉,但不知道 wxDc 是如何工作的,这似乎是 SFML-wxWidgets 集成的核心。我会一一列出我的疑问。
- 我对 SFML dev webpage 提供的旧教程的拍摄:纠正了一些小错误后的最终代码如下所示:
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
class wxSFMLCanvas : public wxControl, public sf::RenderWindow
{
public:
wxSFMLCanvas(wxWindow* Parent = NULL, wxWindowID Id = -1, const wxPoint& Position = wxDefaultPosition,
const wxSize& Size = wxDefaultSize, long Style = 0);
virtual ~wxSFMLCanvas();
private:
DECLARE_EVENT_TABLE()
virtual void OnUpdate();
void OnIdle(wxIdleEvent&);
void OnPaint(wxPaintEvent&);
void OnEraseBackground(wxEraseEvent&);
void OnSize(wxSizeEvent&);
};
void wxSFMLCanvas::OnUpdate()
{
}
void wxSFMLCanvas::OnIdle(wxIdleEvent&)
{
// Send a paint message when the control is idle, to ensure maximum framerate
Refresh();
}
void wxSFMLCanvas::OnPaint(wxPaintEvent&)
{
// Prepare the control to be repainted
wxPaintDC Dc(this);
// Let the derived class do its specific stuff
OnUpdate();
// Display on screen
display();
}
void wxSFMLCanvas::OnEraseBackground(wxEraseEvent&)
{
}
void wxSFMLCanvas::OnSize(wxSizeEvent&)
{
}
wxSFMLCanvas::wxSFMLCanvas(wxWindow* Parent, wxWindowID Id, const wxPoint& Position, const wxSize& Size, long Style) :
wxControl(Parent, Id, Position, Size, Style) {
sf::RenderWindow::create(GetHandle());
}
wxSFMLCanvas::~wxSFMLCanvas()
{
}
class MyCanvas : public wxSFMLCanvas
{
sf::CircleShape circ;
public:
MyCanvas(wxWindow* Parent, wxWindowID Id, wxPoint& Position, wxSize& Size, long Style = 0) : wxSFMLCanvas(Parent, Id, Position, Size, Style) {
// specify circle
circ.setRadius(50.0f);
circ.setOrigin(50.0f,50.0f);
circ.setFillColor(sf::Color::Blue);
circ.setPosition(100.0f, 100.0f);
}
private:
virtual void OnUpdate() {
// Clear the view
clear(sf::Color(0, 128, 128));
// Display the circle in the view
draw(circ);
}
};
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(NULL, wxID_ANY, "SFML wxWidgets", wxDefaultPosition, wxSize(800, 600)) {
wxPoint tmp1 = wxPoint(50, 50);
wxSize tmp2 = wxSize(700, 500);
new MyCanvas(this, wxID_ANY, tmp1, tmp2);
}
};
class MyApplication : public wxApp
{
private:
virtual bool OnInit()
{
// Create the main window
MyFrame* MainFrame = new MyFrame;
MainFrame->Show();
return true;
}
};
IMPLEMENT_APP(MyApplication);
这会抛出一堆未解决的外部问题:
Error LNK2001 unresolved external symbol "protected: virtual struct wxEventTable const * __cdecl wxSFMLCanvas::GetEventTable(void)const " (?GetEventTable@wxSFMLCanvas@@MEBAPEBUwxEventTable@@XZ) test1 C:\Users\rajat\source\repos\test1\test1.obj 1
Error LNK2001 unresolved external symbol "protected: virtual class wxEventHashTable & __cdecl wxSFMLCanvas::GetEventHashTable(void)const " (?GetEventHashTable@wxSFMLCanvas@@MEBAAEAVwxEventHashTable@@XZ) test1 C:\Users\rajat\source\repos\test1\test1.obj 1
Error LNK2019 unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) test1 C:\Users\rajat\source\repos\test1\MSVCRTD.lib(exe_main.obj) 1
此外,我不太明白在这个例子中wxWidgets 应该如何绘制sf::RenderWindow
的内容。如果有人可以纠正此准系统代码以使其正常工作,那将非常有帮助。也希望解释它是如何工作的。
是否有可以与 SFML 一起使用的 wxWidgets 的替代品,或者是否有用于快速简单的图形库的便捷工具?唯一的要求是我应该能够在 MSVS 上为 x64 框架编译它并静态 link 到我的应用程序。我考虑过Qt,但我不能让它自己编译,或者即使我编译,它也只是32位共享库配置。
代码应该如何工作? sf::RenderWindow
是使用 sf::RenderWindow::create(GetHandle())
创建的。它应该自己绘制所有内容吗?还是我必须自己复制 SFML window 的位图并在 wxControl
上绘制?如果有人能阐明它应该如何工作,那将非常有帮助。
您的错误是由于使用 DECLARE_EVENT_TABLE
但未使用任何 wxBEGIN_EVENT_TABLE/wxEND_EVENT_TABLE
,即您从未定义事件 table 也未连接任何事件处理程序。
我对 SFML 一无所知,所以我无法真正帮助您完成其余的工作,但显然绘图应该由您的 wxEVT_PAINT
处理程序完成——一旦您连接了它——只需调用 sf::RenderWindow::Display()
.
我终于让他们一起工作了。这是在单击按钮时显示圆圈的最小代码:
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
class wxSFMLCanvas : public wxControl, public sf::RenderWindow
{
public:
wxSFMLCanvas(wxWindow* Parent = NULL, wxWindowID Id = -1, const wxPoint& Position = wxDefaultPosition,
const wxSize& Size = wxDefaultSize, long Style = 0);
virtual ~wxSFMLCanvas();
};
wxSFMLCanvas::wxSFMLCanvas(wxWindow* Parent, wxWindowID Id, const wxPoint& Position, const wxSize& Size, long Style) :
wxControl(Parent, Id, Position, Size, Style) {
sf::RenderWindow::create(GetHandle());
}
wxSFMLCanvas::~wxSFMLCanvas() {
}
class cMain : public wxFrame
{
wxButton* m_btn1 = nullptr;
wxSFMLCanvas* mycanv = nullptr;
wxDECLARE_EVENT_TABLE();
public:
cMain();
void onBtnClicked(wxCommandEvent &evt);
};
wxBEGIN_EVENT_TABLE(cMain,wxFrame)
EVT_BUTTON(10001, onBtnClicked)
wxEND_EVENT_TABLE()
cMain::cMain() : wxFrame(nullptr, wxID_ANY, "Window", wxPoint(30, 30), wxSize(800, 600)) {
mycanv = new wxSFMLCanvas(this, wxID_ANY, wxPoint(50, 50), wxSize(700, 500));
m_btn1 = new wxButton(this, 10001, "button1", wxPoint(10, 10), wxSize(100, 50));
}
void cMain::onBtnClicked(wxCommandEvent& evt) {
sf::CircleShape circ(50.0f);
circ.setOrigin(50.0f, 50.0f);
circ.setFillColor(sf::Color::Blue);
circ.setPosition(350, 250);
mycanv->draw(circ);
mycanv->display();
}
class myApp : public wxApp
{
cMain* m_Frame1 = nullptr;
public:
myApp();
virtual bool OnInit();
};
wxIMPLEMENT_APP(myApp);
myApp::myApp() {
}
bool myApp::OnInit() {
// Create the main window
m_Frame1 = new cMain;
m_Frame1->Show();
return true;
}
此代码的可执行文件(所有静态链接)约为 10MB(调试模式)~4MB(发布模式)。我将这段代码留在这里以防其他人发现它有用。
我正在做一系列关于物理模拟的应用程序,直到现在我已经完成了其中一些纯粹使用方便的 SFML 库。现在我想给它们添加一些 GUI 元素。我对 wxWidgets 框架和 wxFrames 只是有点熟悉,但不知道 wxDc 是如何工作的,这似乎是 SFML-wxWidgets 集成的核心。我会一一列出我的疑问。
- 我对 SFML dev webpage 提供的旧教程的拍摄:纠正了一些小错误后的最终代码如下所示:
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
class wxSFMLCanvas : public wxControl, public sf::RenderWindow
{
public:
wxSFMLCanvas(wxWindow* Parent = NULL, wxWindowID Id = -1, const wxPoint& Position = wxDefaultPosition,
const wxSize& Size = wxDefaultSize, long Style = 0);
virtual ~wxSFMLCanvas();
private:
DECLARE_EVENT_TABLE()
virtual void OnUpdate();
void OnIdle(wxIdleEvent&);
void OnPaint(wxPaintEvent&);
void OnEraseBackground(wxEraseEvent&);
void OnSize(wxSizeEvent&);
};
void wxSFMLCanvas::OnUpdate()
{
}
void wxSFMLCanvas::OnIdle(wxIdleEvent&)
{
// Send a paint message when the control is idle, to ensure maximum framerate
Refresh();
}
void wxSFMLCanvas::OnPaint(wxPaintEvent&)
{
// Prepare the control to be repainted
wxPaintDC Dc(this);
// Let the derived class do its specific stuff
OnUpdate();
// Display on screen
display();
}
void wxSFMLCanvas::OnEraseBackground(wxEraseEvent&)
{
}
void wxSFMLCanvas::OnSize(wxSizeEvent&)
{
}
wxSFMLCanvas::wxSFMLCanvas(wxWindow* Parent, wxWindowID Id, const wxPoint& Position, const wxSize& Size, long Style) :
wxControl(Parent, Id, Position, Size, Style) {
sf::RenderWindow::create(GetHandle());
}
wxSFMLCanvas::~wxSFMLCanvas()
{
}
class MyCanvas : public wxSFMLCanvas
{
sf::CircleShape circ;
public:
MyCanvas(wxWindow* Parent, wxWindowID Id, wxPoint& Position, wxSize& Size, long Style = 0) : wxSFMLCanvas(Parent, Id, Position, Size, Style) {
// specify circle
circ.setRadius(50.0f);
circ.setOrigin(50.0f,50.0f);
circ.setFillColor(sf::Color::Blue);
circ.setPosition(100.0f, 100.0f);
}
private:
virtual void OnUpdate() {
// Clear the view
clear(sf::Color(0, 128, 128));
// Display the circle in the view
draw(circ);
}
};
class MyFrame : public wxFrame
{
public:
MyFrame() : wxFrame(NULL, wxID_ANY, "SFML wxWidgets", wxDefaultPosition, wxSize(800, 600)) {
wxPoint tmp1 = wxPoint(50, 50);
wxSize tmp2 = wxSize(700, 500);
new MyCanvas(this, wxID_ANY, tmp1, tmp2);
}
};
class MyApplication : public wxApp
{
private:
virtual bool OnInit()
{
// Create the main window
MyFrame* MainFrame = new MyFrame;
MainFrame->Show();
return true;
}
};
IMPLEMENT_APP(MyApplication);
这会抛出一堆未解决的外部问题:
Error LNK2001 unresolved external symbol "protected: virtual struct wxEventTable const * __cdecl wxSFMLCanvas::GetEventTable(void)const " (?GetEventTable@wxSFMLCanvas@@MEBAPEBUwxEventTable@@XZ) test1 C:\Users\rajat\source\repos\test1\test1.obj 1
Error LNK2001 unresolved external symbol "protected: virtual class wxEventHashTable & __cdecl wxSFMLCanvas::GetEventHashTable(void)const " (?GetEventHashTable@wxSFMLCanvas@@MEBAAEAVwxEventHashTable@@XZ) test1 C:\Users\rajat\source\repos\test1\test1.obj 1
Error LNK2019 unresolved external symbol main referenced in function "int __cdecl invoke_main(void)" (?invoke_main@@YAHXZ) test1 C:\Users\rajat\source\repos\test1\MSVCRTD.lib(exe_main.obj) 1
此外,我不太明白在这个例子中wxWidgets 应该如何绘制sf::RenderWindow
的内容。如果有人可以纠正此准系统代码以使其正常工作,那将非常有帮助。也希望解释它是如何工作的。
是否有可以与 SFML 一起使用的 wxWidgets 的替代品,或者是否有用于快速简单的图形库的便捷工具?唯一的要求是我应该能够在 MSVS 上为 x64 框架编译它并静态 link 到我的应用程序。我考虑过Qt,但我不能让它自己编译,或者即使我编译,它也只是32位共享库配置。
代码应该如何工作?
sf::RenderWindow
是使用sf::RenderWindow::create(GetHandle())
创建的。它应该自己绘制所有内容吗?还是我必须自己复制 SFML window 的位图并在wxControl
上绘制?如果有人能阐明它应该如何工作,那将非常有帮助。
您的错误是由于使用 DECLARE_EVENT_TABLE
但未使用任何 wxBEGIN_EVENT_TABLE/wxEND_EVENT_TABLE
,即您从未定义事件 table 也未连接任何事件处理程序。
我对 SFML 一无所知,所以我无法真正帮助您完成其余的工作,但显然绘图应该由您的 wxEVT_PAINT
处理程序完成——一旦您连接了它——只需调用 sf::RenderWindow::Display()
.
我终于让他们一起工作了。这是在单击按钮时显示圆圈的最小代码:
#include <SFML/Graphics.hpp>
#include <wx/wx.h>
class wxSFMLCanvas : public wxControl, public sf::RenderWindow
{
public:
wxSFMLCanvas(wxWindow* Parent = NULL, wxWindowID Id = -1, const wxPoint& Position = wxDefaultPosition,
const wxSize& Size = wxDefaultSize, long Style = 0);
virtual ~wxSFMLCanvas();
};
wxSFMLCanvas::wxSFMLCanvas(wxWindow* Parent, wxWindowID Id, const wxPoint& Position, const wxSize& Size, long Style) :
wxControl(Parent, Id, Position, Size, Style) {
sf::RenderWindow::create(GetHandle());
}
wxSFMLCanvas::~wxSFMLCanvas() {
}
class cMain : public wxFrame
{
wxButton* m_btn1 = nullptr;
wxSFMLCanvas* mycanv = nullptr;
wxDECLARE_EVENT_TABLE();
public:
cMain();
void onBtnClicked(wxCommandEvent &evt);
};
wxBEGIN_EVENT_TABLE(cMain,wxFrame)
EVT_BUTTON(10001, onBtnClicked)
wxEND_EVENT_TABLE()
cMain::cMain() : wxFrame(nullptr, wxID_ANY, "Window", wxPoint(30, 30), wxSize(800, 600)) {
mycanv = new wxSFMLCanvas(this, wxID_ANY, wxPoint(50, 50), wxSize(700, 500));
m_btn1 = new wxButton(this, 10001, "button1", wxPoint(10, 10), wxSize(100, 50));
}
void cMain::onBtnClicked(wxCommandEvent& evt) {
sf::CircleShape circ(50.0f);
circ.setOrigin(50.0f, 50.0f);
circ.setFillColor(sf::Color::Blue);
circ.setPosition(350, 250);
mycanv->draw(circ);
mycanv->display();
}
class myApp : public wxApp
{
cMain* m_Frame1 = nullptr;
public:
myApp();
virtual bool OnInit();
};
wxIMPLEMENT_APP(myApp);
myApp::myApp() {
}
bool myApp::OnInit() {
// Create the main window
m_Frame1 = new cMain;
m_Frame1->Show();
return true;
}
此代码的可执行文件(所有静态链接)约为 10MB(调试模式)~4MB(发布模式)。我将这段代码留在这里以防其他人发现它有用。