带有wxWidgets的独立FileDialog窗口

时间:2014-12-28 19:27:30

标签: c++ wxwidgets

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

此外,我需要拥有自己的main函数,因此我不想使用IMPLEMENT_APP之类的宏。我尝试按照here给出的说明进行操作,并提出了以下最小程序:

#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,我不知道问题来自哪里。有提示吗?

2 个答案:

答案 0 :(得分:0)

好的,在这里摆弄一些代码示例后,对我来说很有用。欢迎评论什么是最佳做法。我所做的是在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尽可能简单)

答案 1 :(得分:0)

我不会那么大胆地​​删除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.
}

我认为那些丑陋的宏可以更好地隔离库初始化代码的未来变化。