【发布时间】:2021-04-19 13:33:32
【问题描述】:
我正在制作一系列关于物理模拟的应用程序,到目前为止,我已经完成了其中一些应用程序,纯粹是使用方便的 SFML 库。现在我想为它们添加一些 GUI 元素。我只是对 wxWidgets 框架和 wxFrames 有点熟悉,但不知道 wxDc 是如何工作的,这似乎是 SFML-wxWidgets 集成的核心。我将一一列出我的查询。
- 我对@987654321@提供的旧教程的拍摄:纠正一些琐碎错误后的最终代码如下所示:
#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 for x64 框架上编译它并静态链接到我的应用程序。我考虑过 Qt,但我不能让它自己编译,或者即使我这样做,它也只是 32 位共享库配置。
-
代码应该如何工作?
sf::RenderWindow是使用sf::RenderWindow::create(GetHandle())创建的。它应该自己绘制所有内容吗?还是我必须自己复制SFML窗口的位图并在wxControl上绘制?如果有人能阐明它应该如何工作,那将非常有帮助。
【问题讨论】:
-
是否有替代 wxWidgets 的方法可以与 SFML 一起使用 Qt 应该可以很好地解决这个问题。
-
对此的另一条评论。请记住,c++ 库的二进制文件通常只与 msvc 或 mingw 兼容,您通常不能将 mingw c++ 二进制文件用于 msvc 或反之亦然。确保您拥有适用于您正在使用的任何编译器的正确二进制文件。此外,Visual Studio 2015 至 2019 版本相互兼容,但与任何其他版本的 msvc 不兼容。
-
@drescherjm 我用错误更新了问题。如果我可以在静态链接模式下为 x64 架构编译它,我可以使用 Qt,但我根本做不到。我在 x64 静态链接配置的 MSVS 上编译了 SFML 和 wxWidgets,并且我正在使用相应的预处理器指令进行静态链接。它们各自工作正常。
-
我在工作中使用 64 位 Qt 已有 13 年,但从未将其用作静态库。相反,我生成了一个 NSIS 安装程序,它具有所有必需的 dll,还包括安装 msvc 可再发行组件的能力。
-
@RajatMondal,请在 MSVC 中打开
minimal示例解决方案并查看其属性。然后在你的项目中做同样的事情。然后它应该可以干净地编译。确保在示例中选择合适的目标来查看 -= 即静态与动态。