FastCAE执行流程
1、FastCAE.exe启动的时候进入主函数(位于main/main.cpp);
2、main函数第一句代码CommandPara para(argc, argv)构造命令行参数对象,初始化成员变量:
1 /** 2 * @brief 是否显示GUI界面 3 */ 4 bool _showGUI{ true }; 5 6 /** 7 * @brief 是否打印帮助信息 8 */ 9 bool _help{ false }; 10 11 /** 12 * @brief 程序启动要执行的python脚本文件 13 */ 14 QString _scriptFile{}; 15 16 /** 17 * @brief 程序启动时要打开的工程文件 18 */ 19 QString _projectFile{};
3、遍历命令行参数,做出相应处理。
1 /** 2 * @brief 遍历命令行参数,i从1开始,跳过程序名称"FastCAE.exe" 3 */ 4 for (int i = 1; i < argc; ++i) 5 { 6 QString arguement = QString(argv[i]).simplified().toLower(); 7 8 /** 9 * @brief 命令行参数包括-nogui的时候,设置成员变量_showGUI为false,并相应的设置PythonAagent的_noGUI。 10 */ 11 if (arguement == "-nogui") 12 { 13 _showGUI = false; 14 Py::PythonAagent::getInstance()->setNoGUI(!_showGUI); 15 continue; 16 } 17 /** 18 * @brief 命令行参数包括-i的时候,将argv[++i]的值设置为启动脚本_scriptFile。 19 */ 20 else if (arguement == "-i") 21 { 22 char* c = argv[++i]; 23 _scriptFile = QString::fromLocal8Bit(c); 24 continue; 25 } 26 /** 27 * @brief 命令行参数包括-p的时候,将argv[++i]的值设置为工程文件_projectFile。 28 */ 29 else if (arguement.contains("-p")) 30 { 31 char* c = argv[++i]; 32 _projectFile = QString::fromLocal8Bit(c); 33 continue; 34 } 35 /** 36 * @brief 命令行参数包括-help的时候,设置成员变量_help为true。 37 */ 38 else if (arguement.contains("-help")) 39 { 40 _help = true; 41 continue; 42 } 43 }
4、在Windows环境下,根据成员变量_help和_showGUI判断是否打印帮助信息到控制台。
1 #ifdef Q_OS_WIN 2 if (_help || (!_showGUI)) 3 connectToConsole(); 4 #endif
5、返回main函数,执行下面代码:
if (para.isHelp()) return 1;
isHelp()方法的定义如下:
1 bool CommandPara::isHelp() 2 { 3 if (!_help) return false; 4 std::cout << std::endl; 5 std::cout << " -help Show those help info" << std::endl; 6 std::cout << " -i Execute a script"<<std::endl; 7 std::cout << " -nogui Run without GUI" << std::endl; 8 std::cout << " -p Open a project" << std::endl; 9 return true; 10 }
6、初始化QApplication app(argc, argv)。
7、初始化Setting::BusAPI,并获取是否使用ribbon风格。
bool isRibbon = Setting::BusAPI::instance()->isUseRibbon();
其中,在初始化的时候初始化了一些成员变量,这些成员变量主要负责FastCAE.ini的配置文件:
1 static BusAPI *_ins; 2 /** 3 * @brief 主要配置 4 */ 5 MainSetting *_mainSetting{}; 6 7 /** 8 * @brief 绘图配置,对应于FastCAE的设置-绘图选项 9 */ 10 GraphOption *_graphOption{}; 11 12 /** 13 * @brief 消息配置 14 */ 15 MessageSetting *_messageSetting{}; 16 17 GUI::MainWindow *_mainWindow{};
Setting::BusAPI在初始化的时候(构造函数)还调用了readINI(),该函数的代码如下:
1 void BusAPI::readINI() 2 { 3 /** 4 * @brief 获取FastCAE.exe同目录下的FastCAE.ini文件 5 */ 6 QString path = qApp->applicationDirPath(); 7 QSettings settingReader(path + "/FastCAE.ini", QSettings::IniFormat); 8 9 /** 10 * @brief 从FastCAE.ini文件读取配置 11 */ 12 _mainSetting->readINI(&settingReader); 13 _graphOption->readINI(&settingReader); 14 _messageSetting->readINI(&settingReader); 15 }
8、以isRibbon为参数构造GUI:MainWindow。
GUI::MainWindow mainwindow(isRibbon);
构造的过程初始化了一些成员变量,具体如下:
1 Ui::MainWindowRibbon* _ui{}; 2 3 /** 4 * @brief 维护翻译文件的资源列表 5 */ 6 Translator* _translator{}; 7 8 /** 9 * @brief 信号句柄 10 */ 11 SignalHandler* _signalHandler{}; 12 13 /** 14 * @brief 子窗口管理器 15 */ 16 SubWindowManager* _subWindowManager{}; 17 18 /** 19 * @brief 自定义助手 20 */ 21 CustomizerHelper* _customizerHelper{}; 22 23 QString _currentFile{}; 24 QString _MD5{}; 25 26 /** 27 * @brief 控制面板 28 */ 29 MainWidget::ControlPanel* _controlPanel{}; 30 31 /** 32 * @brief 进程窗口 33 */ 34 MainWidget::ProcessWindow* _processWindow{}; 35 36 /** 37 * @brief 消息窗口 38 */ 39 MainWidget::MessageWindow* _messageWindow{}; 40 41 /** 42 * @brief 收集无参数的信号,转换成有参数的信号 43 */ 44 QSignalMapper* _viewSignalMapper{}; 45 QSignalMapper* _selectSignalMapper{}; 46 QSignalMapper* _selectGeometryModeMapper{}; 47 QSignalMapper* _recentFileMapper{}; 48 49 QMenu *_recentMenu{}; 50 QLabel* _graphRange{};
MainWindow的构造函数具体代码如下:
1 MainWindow::MainWindow(bool useRibbon) : SARibbonMainWindow(nullptr, useRibbon), _ui(new Ui::MainWindowRibbon) 2 { 3 if (useRibbon) 4 _ui->setupRibbonUi(this); 5 else 6 _ui->setupUi(this); 7 8 /** 9 * @brief 设置上下文菜单策略。 10 */ 11 this->setContextMenuPolicy(Qt::NoContextMenu); 12 13 /** 14 * @brief 获取当前配置的本地化信息。 15 */ 16 QString lang = Setting::BusAPI::instance()->getLanguage(); 17 18 /** 19 * @brief 实例化MainWidget::ControlPanel、MainWidget::MessageWindow、MainWidget::ProcessWindow 20 * 并使用addDockWidget函数添加到MainWindow窗口。 21 */ 22 registerMoudel(); 23 24 /** 25 * @brief 实例化GUI::SignalHandler,构造函数中将工程树、工具栏的鼠标事件连接到_signalHandler。 26 */ 27 _signalHandler = new SignalHandler(this); 28 29 /** 30 * @brief 实例化GUI::Translator,内部维护了一个QList<QTranslator*>对象,通过removeTranslator和installTranslator实现语言切换。 31 */ 32 _translator = new Translator(); 33 34 /** 35 * @brief 实例化GUI::SubWindowManager,构造函数主要将一些窗口的关闭、视图调整、保存图片的信号连接到槽函数。 36 */ 37 _subWindowManager = new SubWindowManager(this, _ui->mdiArea, _signalHandler, _controlPanel); 38 39 /** 40 * @brief 主要将菜单栏、工具栏的按钮点击事件连接到槽函数。 41 */ 42 connectSignals(); 43 44 /** 45 * @brief 设置QMdiArea的一些属性。 46 */ 47 _ui->mdiArea->setViewMode(QMdiArea::TabbedView); 48 _ui->mdiArea->setTabPosition(QTabWidget::North); 49 _ui->mdiArea->setTabShape(QTabWidget::Rounded); 50 51 /** 52 * @brief 翻译界面内容,包括主窗口、子窗口、插件。 53 * @note 该函数会实例化ConfigOption::GlobalConfig用于读取定制化信息,但此时并没有读取,只是实例化对象。 54 */ 55 this->ChangeLanguage(lang); 56 57 /** 58 * @brief 获取FastCAE的工作空间,如果获取到空值,则弹出设置工作空间的对话框。 59 */ 60 QString workingdir = Setting::BusAPI::instance()->getWorkingDir(); 61 if (workingdir.isEmpty()) 62 setWorkingDir(); 63 64 /** 65 * @brief 为Setting::BusAPI的成员变量_mainWindow赋值。 66 */ 67 Setting::BusAPI::instance()->setMainWindow(this); 68 69 /** 70 * @brief 获取配置信息中的绘图配置信息。 71 */ 72 Setting::GraphOption *gp = Setting::BusAPI::instance()->getGraphOption(); 73 74 /** 75 * @brief 根据读取到的绘图信息,设置一些窗口组件的状态。 76 */ 77 _ui->actionDisplayPoint->setChecked(gp->isShowGeoPoint()); 78 _ui->actionDisplayCurve->setChecked(gp->isShowGeoEdge()); 79 _ui->actionDisplayFace->setChecked(gp->isShowGeoSurface()); 80 81 /** 82 * @brief 设置几何点线面的显影按钮状态。 83 */ 84 this->setGeometryDisplay(); 85 86 /** 87 * @brief 设置最近文档的菜单及相应的信号槽 88 */ 89 updateRecentMenu(); 90 setCurrentFile(""); 91 92 /** 93 * @brief 设置草图菜单的显影状态,启动软件时,默认隐藏草图菜单 94 */ 95 this->startSketch(false); 96 97 98 QString slogo = ConfigOption::ConfigOption::getInstance()->getGlobalConfig()->getLogo(); 99 this->setIcon(QApplication::applicationDirPath() + "/../ConfigFiles/icon/" + slogo); 100 101 /** 102 * @brief 获取子窗口、几何、网格、模型的管理器,以获得的内容为数据设置action的可用状态。 103 */ 104 _signalHandler->updateActionsStates(); 105 106 /** 107 * @brief 初始化GUI::MainWindowPy,实例化Py::PythonAagent赋值给成员变量_pyAgent。 108 */ 109 MainWindowPy::init(this, _signalHandler); 110 111 /** 112 * @brief 初始化Gmsh::GmshModule。 113 */ 114 Gmsh::GmshModule::getInstance(this); 115 116 /** 117 * @brief 在状态栏设置绘图窗口的尺寸信息。 118 */ 119 this->showGraphRange(0, 0); 120 121 /** 122 * @brief 设置python37的信息,开始脚本录制线程RecordThread。 123 */ 124 Py::PythonAagent::getInstance()->initialize(this); 125 126 /** 127 * @brief 加载插件。 128 */ 129 Plugins::PluginManager::getInstance()->loadPlugs(this); 130 131 132 _customizerHelper = new CustomizerHelper(this, _ui); 133 _customizerHelper->registerInterface(); 134 135 /** 136 * @brief 加载首页网页。 137 */ 138 _subWindowManager->openStartPage(); 139 140 /** 141 * @brief 根据RecordScript.py是否存在,弹出是否加载脚本的对话框。 142 */ 143 isLoadRecordScripFile(); 144 }
9、回到main.cpp,加载qss样式文件
1 XBeautyUI::instance()->setQssFilePath(":/Beauty/QUI/beauty/qianfan.qss"); 2 XBeautyUI::instance()->autoSetStyle(); 3 QString qssFileName = XBeautyUI::instance()->qssFilePath(); 4 5 QFile qssFile(qssFileName); 6 if (qssFile.exists()) 7 { 8 qssFile.open(QIODevice::ReadOnly); 9 QString style = qssFile.readAll(); 10 qApp->setStyleSheet(style); 11 qssFile.close(); 12 }
10、执行para.exec,显示MainWindow。
1 if (para.exec(&mainwindow)) 2 emit mainwindow.sendInfoToStatesBar(QString("Version: %1").arg(FASTCAE_VERSION)); 3 else return 1;
11、至此,软件的启动过程就分析清楚了。