带有 wxWidgets 的独立文件对话框窗口

Standalone FileDialog window with wxWidgets

本文关键字:对话框 窗口 文件 独立 wxWidgets 带有      更新时间:2023-10-16

我正在尝试使用 wxWidgets 以跨平台的方式创建一个打开/保存 FileDialog 窗口。所以我查看了文档中的示例。我还想创建没有父窗口的独立窗口,因为我没有在程序的其他地方使用 wxApp/wxWindow 的任何其他实例。

此外,我需要有自己的main函数,所以我不想使用宏,例如 IMPLEMENT_APP .我尝试按照此处给出的说明进行操作,并提出了以下最小程序:

#include <wx/wx.h>
#include <string>
#include <iostream>
std::string openFile() {
    wxFileDialog openFileDialog(NULL,  _("Open XYZ file"), "", "",
        "XYZ files (*.xyz)|*.xyz", wxFD_OPEN|wxFD_FILE_MUST_EXIST);
    if (openFileDialog.Show() == wxID_CANCEL)
        return ""; // the user changed idea...
    // proceed loading the file chosen by the user;
    return "something";
}
int main(int argc, char *argv[]) {
    std::cout << wxEntryStart(argc, argv) << std::endl;
    std::string s = openFile();
    wxEntryCleanup();
}

这是我用来编译代码的CMakeLists.txt:

CMake_Minimum_Required(VERSION 2.8.11)
Project(test)
Find_Package(wxWidgets REQUIRED)
Include(${wxWidgets_USE_FILE})
Add_Executable(test main.cpp)
Target_Link_Libraries(test ${wxWidgets_LIBRARIES})

尽管如此,当我运行这个程序时,我得到了一个分段错误,尽管wxEntryStart返回true,我不知道问题来自哪里。有什么提示吗?

我不会那么大胆地剥离wx的初始化代码。它今天可能有效,但在下一个版本中,谁知道呢......

这是我使用的:

class MyApp : public wxApp { };
wxIMPLEMENT_APP_NO_MAIN(MyApp);
int main()
{
    wxDISABLE_DEBUG_SUPPORT();
    int dummy = 0;
    if(!wxEntryStart(dummy, static_cast<wxChar**>(nullptr)))
        return 1;
    auto onx1 = on_exit([]{ wxEntryCleanup(); }); //using RAII for cleanup
    //Other initialization, create main window, show it.
    wxGetApp().OnRun(); //This starts the event loop.
    //In your case, it looks like ShowModal's event loop is enough, 
    //so you don't need this.
}

我认为这些宏虽然丑陋,但可以更好地隔离库初始化代码中的未来更改。

好的,经过一些摆弄,这里有一个适合我的代码示例。欢迎评论什么是最佳实践。我所做的是保留ShowModal()而不是Show() openFile函数。我还创建了单例wxApp实例。最终代码在这里:

#include <wx/wx.h>
#include <string>
#include <iostream>
std::string openFile() {
    wxFileDialog openFileDialog(NULL,  _("Open XYZ file"), "", "",
        "XYZ files (*.xyz)|*.xyz", wxFD_OPEN|wxFD_FILE_MUST_EXIST);
    if (openFileDialog.ShowModal() == wxID_CANCEL)
        return ""; // the user changed idea...
    // proceed loading the file chosen by the user;
    return "something";
}
int main(int argc, char *argv[]) {
    wxApp::SetInstance( new wxApp() );
    wxEntryStart(argc, argv);
    std::string s = openFile();
    wxEntryCleanup();
}

不确定这是否完全无泄漏,因为valgrind似乎在退出后有点抱怨。关于我是否也可以将wxEntryStart()放在openFile()函数中的任何提示欢迎(我保证这是唯一使用 wxWidgets lib 的地方,我想要一个尽可能简单的 API)。