目录

1 MainGui.cpp源代码

2 int main()函数分析

3 编译运行截图


 

FreeCADMain项目下的MainGui.cpp

1 MainGui.cpp源代码
int main( int argc, char ** argv )
{
#if defined (FC_OS_LINUX) || defined(FC_OS_BSD)
    setlocale(LC_ALL, ""); // use native environment settings

    // Make sure to setup the Qt locale system before setting LANG and LC_ALL to C.
    // which is needed to use the system locale settings.
    (void)QLocale::system();
    // See https://forum.freecad.org/viewtopic.php?f=18&t=20600
    // See Gui::Application::runApplication()
    putenv("LC_NUMERIC=C");
    putenv("PYTHONPATH=");
#elif defined(FC_OS_MACOSX)
    (void)QLocale::system();
    putenv("PYTHONPATH=");
#elif defined(__MINGW32__)
    const char* mingw_prefix = getenv("MINGW_PREFIX");
    const char* py_home = getenv("PYTHONHOME");
    if (!py_home && mingw_prefix)
        _putenv_s("PYTHONHOME", mingw_prefix);
#else
    _putenv("PYTHONPATH=");
    // https://forum.freecad.org/viewtopic.php?f=4&t=18288
    // https://forum.freecad.org/viewtopic.php?f=3&t=20515
    const char* fc_py_home = getenv("FC_PYTHONHOME");
    if (fc_py_home)
        _putenv_s("PYTHONHOME", fc_py_home);
    else
        _putenv("PYTHONHOME=");
#endif

#if defined (FC_OS_WIN32)
    // we need to force Coin not to use Freetype in order to find installed fonts on Windows
    // see https://forum.freecad.org/viewtopic.php?p=485142#p485016
    _putenv("COIN_FORCE_FREETYPE_OFF=1");

    int argc_ = argc;
    QVector<QByteArray&gt; data;
    QVector<char *&gt; argv_;

    // get the command line arguments as unicode string
    {
        QCoreApplication app(argc, argv);
        QStringList args = app.arguments();
        for (QStringList::iterator it = args.begin(); it != args.end(); ++it) {
            data.push_back(it->toUtf8());
            argv_.push_back(data.back().data());
        }
        argv_.push_back(0); // 0-terminated string
    }
#endif

    // Name and Version of the Application
    App::Application::Config()["ExeName"] = "FreeCAD";
    App::Application::Config()["ExeVendor"] = "FreeCAD";
    App::Application::Config()["AppDataSkipVendor"] = "true";
    App::Application::Config()["MaintainerUrl"] = "http://www.freecad.org/wiki/Main_Page";

    // set the banner (for logging and console)
    App::Application::Config()["CopyrightInfo"] = sBanner;
    App::Application::Config()["AppIcon"] = "freecad";
    App::Application::Config()["SplashScreen"] = "freecadsplash";
    App::Application::Config()["AboutImage"] = "freecadabout";
    App::Application::Config()["StartWorkbench"] = "StartWorkbench";
    //App::Application::Config()["HiddenDockWindow"] = "Property editor";
    App::Application::Config()["SplashAlignment" ] = "Bottom|Left";
    App::Application::Config()["SplashTextColor" ] = "#8aadf4"; // light blue
    App::Application::Config()["SplashInfoColor" ] = "#8aadf4"; // light blue 
    App::Application::Config()["SplashInfoPosition" ] = "6,75";

    QGuiApplication::setDesktopFileName(QStringLiteral("org.freecad.FreeCAD.desktop"));

    try {
        // Init phase ===========================================================
        // sets the default run mode for FC, starts with gui if not overridden in InitConfig...
        App::Application::Config()["RunMode"] = "Gui";
        App::Application::Config()["Console"] = "0";
        App::Application::Config()["LoggingConsole"] = "1";

        // Inits the Application
#if defined (FC_OS_WIN32)
        App::Application::init(argc_, argv_.data());
#else
        App::Application::init(argc, argv);
#endif
#if defined(_MSC_VER)
        // create a dump file when the application crashes
        std::string dmpfile = App::Application::getUserAppDataDir();
        dmpfile += "crash.dmp";
        InitMiniDumpWriter(dmpfile);
#endif
        std::map<std::string, std::string>::iterator it = App::Application::Config().find("NavigationStyle");
        if (it != App::Application::Config().end()) {
            ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
            // if not already defined do it now (for the very first start)
            std::string style = hGrp->GetASCII("NavigationStyle", it->second.c_str());
            hGrp->SetASCII("NavigationStyle", style.c_str());
        }

        Gui::Application::initApplication();

        // Only if 'RunMode' is set to 'Gui' do the replacement
        if (App::Application::Config()["RunMode"] == "Gui")
            Base::Interpreter().replaceStdOutput();
    }
    catch (const Base::UnknownProgramOption&amp; e) {
        QApplication app(argc,argv);
        QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());
        QString msg = QString::fromLatin1(e.what());
        QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>");
        QMessageBox::critical(nullptr, appName, s);
        exit(1);
    }
    catch (const Base::ProgramInformation&amp; e) {
        QApplication app(argc,argv);
        QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());
        QString msg = QString::fromUtf8(e.what());
        QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>");

        QMessageBox msgBox;
        msgBox.setIcon(QMessageBox::Information);
        msgBox.setWindowTitle(appName);
        msgBox.setDetailedText(msg);
        msgBox.setText(s);
        msgBox.exec();
        exit(0);
    }
    catch (const Base::Exception&amp; e) {
        // Popup an own dialog box instead of that one of Windows
        QApplication app(argc,argv);
        QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());
        QString msg;
        msg = QObject::tr("While initializing %1 the following exception occurred: '%2'nn"
                          "Python is searching for its files in the following directories:n%3nn"
                          "Python version information:n%4n")
                          .arg(appName, QString::fromUtf8(e.what()),
                          QString::fromUtf8(Py_EncodeLocale(Py_GetPath(),nullptr)), QString::fromLatin1(Py_GetVersion()));
        const char* pythonhome = getenv("PYTHONHOME");
        if (pythonhome) {
            msg += QObject::tr("nThe environment variable PYTHONHOME is set to '%1'.")
                .arg(QString::fromUtf8(pythonhome));
            msg += QObject::tr("nSetting this environment variable might cause Python to fail. "
                "Please contact your administrator to unset it on your system.nn");
        } else {
            msg += QObject::tr("nPlease contact the application's support team for more information.nn");
        }

        QMessageBox::critical(nullptr, QObject::tr("Initialization of %1 failed").arg(appName), msg);
        exit(100);
    }
    catch (...) {
        // Popup an own dialog box instead of that one of Windows
        QApplication app(argc,argv);
        QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());
        QString msg = QObject::tr("Unknown runtime error occurred while initializing %1.nn"
                                  "Please contact the application's support team for more information.nn").arg(appName);
        QMessageBox::critical(nullptr, QObject::tr("Initialization of %1 failed").arg(appName), msg);
        exit(101);
    }

    // Run phase ===========================================================
    Base::RedirectStdOutput stdcout;
    Base::RedirectStdLog    stdclog;
    Base::RedirectStdError  stdcerr;
    std::streambuf* oldcout = std::cout.rdbuf(&amp;stdcout);
    std::streambuf* oldclog = std::clog.rdbuf(&amp;stdclog);
    std::streambuf* oldcerr = std::cerr.rdbuf(&amp;stdcerr);

    try {
        // if console option is set then run in cmd mode
        if (App::Application::Config()["Console"] == "1")
            App::Application::runApplication();
        if (App::Application::Config()["RunMode"] == "Gui" ||
            App::Application::Config()["RunMode"] == "Internal")
            Gui::Application::runApplication();
        else
            App::Application::runApplication();
    }
    catch (const Base::SystemExitException&amp; e) {
        exit(e.getExitCode());
    }
    catch (const Base::Exception&amp; e) {
        e.ReportException();
        exit(1);
    }
    catch (const std::exception& e) {
        Base::Console().Error("Application unexpectedly terminated: %sn", e.what());
        exit(1);
    }
    catch (...) {
        Base::Console().Error("Application unexpectedly terminatedn");
        exit(1);
    }

    std::cout.rdbuf(oldcout);
    std::clog.rdbuf(oldclog);
    std::cerr.rdbuf(oldcerr);

    // Destruction phase ===========================================================
    Base::Console().Log("%s terminating...n",App::Application::Config()["ExeName"].c_str());

    // cleans up
    App::Application::destruct();

    Base::Console().Log("%s completely terminatedn",App::Application::Config()["ExeName"].c_str());

    return 0;
}
2 int main()函数分析
int main( int argc, char ** argv )  
{  
    // 如果操作系统是Linux或BSD,则设置本地化环境当前环境设置  
#if defined (FC_OS_LINUX) || defined(FC_OS_BSD)  
    setlocale(LC_ALL, ""); // use native environment settings  
  
    // 在将LANG和LC_ALL设置为C之前,确保设置了Qt的本地化系统,  
    // 这样才能使用系统本地化设置。  
    // See https://forum.freecad.org/viewtopic.php?f=18&t=20600  
    // See Gui::Application::runApplication()  
    putenv("LC_NUMERIC=C");  
    putenv("PYTHONPATH=");  
#elif defined(FC_OS_MACOSX)  
    // 对于Mac OS X,同样设置本地化系统,并且设置PYTHONPATH环境变量为空  
    (void)QLocale::system();  
    putenv("PYTHONPATH=");  
#elif defined(__MINGW32__)  
    // 对于MinGW,获取MINGW_PREFIX环境变量,并获取PYTHONHOME环境变量,  
    // 如果PYTHONHOME未设置且MINGW_PREFIX存在,则将PYTHONHOME设置为MINGW_PREFIX  
    const char* mingw_prefix = getenv("MINGW_PREFIX");  
    const char* py_home = getenv("PYTHONHOME");  
    if (!py_home && mingw_prefix)  
        _putenv_s("PYTHONHOME", mingw_prefix);  
#else  
    // 对于其他操作系统,将PYTHONPATH环境变量设置为空,并获取FC_PYTHONHOME环境变量,  
    // 如果存在,则将PYTHONHOME设置为FC_PYTHONHOME;否则,将PYTHONHOME环境变量设置为空  
    _putenv("PYTHONPATH=");  
    // https://forum.freecad.org/viewtopic.php?f=4&t=18288  
    // https://forum.freecad.org/viewtopic.php?f=3&t=20515  
    const char*fc_py_home = getenv("FC_PYTHONHOME");  
    if (fc_py_home)  
        _putenv_s("PYTHONHOME",fc_py_home);  
    else  
        _putenv("PYTHONHOME=");  
#endif  
  
#if defined (FC_OS_WIN32)  
    // 我们需要强制Coin不使用Freetype找到Windows上已安装字体,  
    // 见 https://forum.freecad.org/viewtopic.php?p=485142#p485016  
    // 设置COIN_FORCE_FREETYPE_OFF环境变量为1,强制Coin不使用Freetype  
    _putenv("COIN_FORCE_FREETYPE_OFF=1");  
  
    // 对于Windows,我们创建一个新的命令行参数数组,并将其转换unicode字符串格式  
    int argc_ = argc;  
    QVector<QByteArray> data;  
    QVector<char *> argv_;  
  
    // 获取命令行参数并将其转换unicode字符串格式  
    {  
        QCoreApplication app(argc, argv);  // 使用QCoreApplication来获取命令参数列表  
        QStringList args = app.arguments();  // 获取命令参数列表(包括程序名称)  
        for (QStringList::iterator it = args.begin(); it != args.end(); ++it) {  // 遍历参数列表转换utf-8格式的字节数组并存入datadata.push_back(it->toUtf8());  // 转换参数utf-8格式的字节数组并存入data中  
            argv_.push_back(data.back().data()); 

            argv_.push_back(0); // 0-terminated string
    }
#endif

        // 应用程序名称版本  
    App::Application::Config()["ExeName"] = "FreeCAD"; // 应用程序名称  
    App::Application::Config()["ExeVendor"] = "FreeCAD"; // 应用程序供应商  
    App::Application::Config()["AppDataSkipVendor"] = "true"; // 跳过应用程序数据供应商  
    App::Application::Config()["MaintainerUrl"] = "http://www.freecad.org/wiki/Main_Page"; // 维护者URL  
  
// 设置横幅(用于日志记录控制台)  
    App::Application::Config()["CopyrightInfo"] = sBanner; // 版权信息  
    App::Application::Config()["AppIcon"] = "freecad"; // 应用程序图标  
    App::Application::Config()["SplashScreen"] = "freecadsplash"; // 启动画面  
    App::Application::Config()["AboutImage"] = "freecadabout"; // 关于图像  
    App::Application::Config()["StartWorkbench"] = "StartWorkbench"; // 启动工作台  
//App::Application::Config()["HiddenDockWindow"] = "Property editor"; // 隐藏停靠窗口  
    App::Application::Config()["SplashAlignment" ] = "Bottom|Left"; // 启动画对齐方式  
    App::Application::Config()["SplashTextColor" ] = "#8aadf4"; // 启动画文本颜色(浅蓝色)  
    App::Application::Config()["SplashInfoColor" ] = "#8aadf4"; // 启动画信息颜色(浅蓝色)  
    App::Application::Config()["SplashInfoPosition" ] = "6,75"; // 启动画面信息位置  
  
QGuiApplication::setDesktopFileName(QStringLiteral("org.freecad.FreeCAD.desktop")); // 设置桌面文件名  
  
try {  
    // 初始化阶段 ===========================================================  
    // 设置FC的默认运行模式,如果没有在InitConfig中覆盖,则从GUI开始  
    App::Application::Config()["RunMode"] = "Gui"; // 运行模式(GUI)  
    App::Application::Config()["Console"] = "0"; // 控制台模式(0-无,1-有)  
    App::Application::Config()["LoggingConsole"] = "1"; // 日志记录控制台(1-是,0-否)  
  
    // 初始化应用程序  
#if defined (FC_OS_WIN32)  
    App::Application::init(argc_, argv_.data()); // 在Windows平台初始化应用程序  
#else  
    App::Application::init(argc, argv); // 在其他平台初始化应用程序  
#endif  
#if defined(_MSC_VER)  
    // 当应用程序崩溃创建一个转储文件  
    std::string dmpfile = App::Application::getUserAppDataDir(); // 获取用户应用程序数据目录  
    dmpfile += "crash.dmp"; // 添加文件后缀名  
    InitMiniDumpWriter(dmpfile); // 初始化MiniDumpWriter,用于生成.dmp文件,有助于程序崩溃后的调试  
#endif
#if defined(_MSC_VER)  
        // 当应用程序崩溃创建一个转储文件  
        // create a dump file when the application crashes  
        std::string dmpfile = App::Application::getUserAppDataDir();  
        dmpfile += "crash.dmp";  
        InitMiniDumpWriter(dmpfile);  
#endif  
  
        // 查找配置文件中的 "NavigationStyle" 键值对  
        std::map<std::string, std::string>::iterator it = App::Application::Config().find("NavigationStyle");  
        if (it != App::Application::Config().end()) {  
            // 通过路径获取用户参数组,并设置 "NavigationStyle" 的值  
            ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");  
            // 如果未定义,则立即定义(对于第一次启动)  
            std::string style = hGrp->GetASCII("NavigationStyle", it->second.c_str());  
            hGrp->SetASCII("NavigationStyle", style.c_str());  
        }  
  
        // 初始化应用程序  
        Gui::Application::initApplication();  
  
        // 如果 'RunMode' 被设置为 'Gui',则替换标准输出  
        // Only if 'RunMode' is set to 'Gui' do the replacement  
        if (App::Application::Config()["RunMode"] == "Gui")  
            Base::Interpreter().replaceStdOutput();  
    }  
    catch (const Base::UnknownProgramOption& e) {  
        // 捕获异常用于处理未知的程序选项问题  
        QApplication app(argc,argv);  
        QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());  
        QString msg = QString::fromLatin1(e.what());  
        QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>");  
        QMessageBox::critical(nullptr, appName, s);  
        exit(1);  
    }  
    catch (const Base::ProgramInformation& e) {  
        // 捕获异常用于处理程序信息问题  
        QApplication app(argc,argv);  
        QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());  
        QString msg = QString::fromUtf8(e.what());  
        QString s = QLatin1String("<pre>") + msg + QLatin1String("</pre>");  
  
        QMessageBox msgBox;  
        msgBox.setIcon(QMessageBox::Information);  
        msgBox.setWindowTitle(appName);  
        msgBox.setDetailedText(msg);  
        msgBox.setText(s);  
        msgBox.exec();  
        exit(0);  
    }
    catch (const Base::Exception& e) {  
        // 捕获Base::Exception类型异常  
        // 弹出自定义对话框,而不是Windows的对话框  
        // Popup an own dialog box instead of that one of Windows  
        QApplication app(argc,argv);  
        QString appName = QString::fromLatin1(App::Application::Config()        ["ExeName"].c_str());  
        QString msg;  
  
        // 使用占位符构建错误消息,其中%1表示应用名称,%2表示异常信息,%3表示Python正在搜索目录,%4表示Python版本信息  
        msg = QObject::tr("While initializing %1 the following exception occurred: '%2'nn"  
                          "Python is searching for its files in the following directories:n%3nn"  
                          "Python version information:n%4n")  
                          .arg(appName, QString::fromUtf8(e.what()),  
                          QString::fromUtf8(Py_EncodeLocale(Py_GetPath(),nullptr)), QString::fromLatin1(Py_GetVersion()));  
  
        const char* pythonhome = getenv("PYTHONHOME");  
        if (pythonhome) {  
            // 如果环境变量PYTHONHOME被设置,则添加相应的错误消息  
            msg += QObject::tr("nThe environment variable PYTHONHOME is set to '%1'.")  
                .arg(QString::fromUtf8(pythonhome));  
            msg += QObject::tr("nSetting this environment variable might cause Python to fail. "  
                "Please contact your administrator to unset it on your system.nn");  
        } else {  
            // 如果环境变量PYTHONHOME没有被设置,则添加相应的错误消息  
            msg += QObject::tr("nPlease contact the application's support team for more information.nn");  
        }  
  
        // 显示错误消息对话框标题为应用名称,内容错误消息然后退出程序并返回错误码100  
        QMessageBox::critical(nullptr, QObject::tr("Initialization of %1 failed").arg(appName), msg);  
        exit(100);  
    }
// 捕获任何异常用于处理未知的运行错误  
catch (...) {  
    // 弹出自定义的对话框,而不是Windows的系统对话框  
    // Popup an own dialog box instead of that one of Windows  
    QApplication app(argc,argv);  
    QString appName = QString::fromLatin1(App::Application::Config()["ExeName"].c_str());  
    QString msg = QObject::tr("Unknown runtime error occurred while initializing %1.nn"  
                              "Please contact the application's support team for more information.nn").arg(appName);  
    // 显示错误消息的对话框,标题为应用名称,内容错误消息,然后退出程序并返回错误码101  
    QMessageBox::critical(nullptr, QObject::tr("Initialization of %1 failed").arg(appName), msg);  
    exit(101);  
}  
  
// 运行阶段 ===========================================================  
// 重定向标准输出流、标准日志流和标准错误流  
    Base::RedirectStdOutput stdcout;  
    Base::RedirectStdLog    stdclog;  
    Base::RedirectStdError  stdcerr;  
// 保存旧的cout、clog和cerr缓冲区指针用于后续恢复  
    std::streambuf* oldcout = std::cout.rdbuf(&stdcout);  
    std::streambuf* oldclog = std::clog.rdbuf(&stdclog);  
    std::streambuf* oldcerr = std::cerr.rdbuf(&stdcerr);  
  
try {  
    // 如果设置了控制台选项,则在命令模式运行应用程序  
    // if console option is set then run in cmd mode  
    if (App::Application::Config()["Console"] == "1")  
        App::Application::runApplication();  
    // 如果运行模式为Gui或Internal,则在GUI模式下运行应用程序  
    if (App::Application::Config()["RunMode"] == "Gui" ||  
        App::Application::Config()["RunMode"] == "Internal")  
        Gui::Application::runApplication();  
    // 否则,在默认模式下运行应用程序  
    else  
        App::Application::runApplication();  
}  
// 捕获Base::SystemExitException异常,根据其退出码退出程序  
catch (const Base::SystemExitException& e) {  
    exit(e.getExitCode());  
}  
// 捕获Base::Exception异常,报告异常并退出程序,返回状态码1  
catch (const Base::Exception& e) {  
    e.ReportException();  
    exit(1);  
}  
// 捕获std::exception异常,输出错误信息并退出程序,返回状态码1  
catch (const std::exception& e) {  
    Base::Console().Error("Application unexpectedly terminated: %sn", e.what());  
    exit(1);  
}  
// 捕获其他所有异常,输出错误信息并退出程序,返回状态码1  
catch (...) {  
    Base::Console().Error("Application unexpectedly terminatedn");  
    exit(1);  
}  
  
// 恢复旧的cout、clog和cerr缓冲区指针以便后续正常输出流控制恢复正常状态  
    std::cout.rdbuf(oldcout);  
    std::clog.rdbuf(oldclog);  
    std::cerr.rdbuf(oldcerr);
// 销毁阶段 ===========================================================  
// 记录应用程序终止信息  
    Base::Console().Log("%s terminating...n",App::Application::Config()    ["ExeName"].c_str());  
  
// 清理资源  
// cleans up  
    App::Application::destruct();  
  
// 记录应用程序完全终止信息  
    Base::Console().Log("%s completely terminatedn",App::Application::Config()    ["ExeName"].c_str());  
  
// 返回0,表示程序正常结束  
    return 0;
}
3 编译运行截图

原文地址:https://blog.csdn.net/weixin_44270564/article/details/134754163

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_45036.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注