浅谈return (app->main(argc-1, argv+1));

本文介绍了一种特殊的程序执行方式:跳过程序自身,将命令行参数传递给main函数执行。具体实现包括调整命令行参数数目并从argv[1]开始传递。
就是跳过执行程序自己,把执行程序原来的参数传递给函数main
命令行参数数目-1,命令行参数从argv[1]开始
/**************************************************************************** ** ** This file is part of the LibreCAD project, a 2D CAD program ** ** Copyright (C) 2010 R. van Twisk (librecad@rvt.dds.nl) ** Copyright (C) 2001-2003 RibbonSoft. All rights reserved. ** ** ** This file may be distributed and/or modified under the terms of the ** GNU General Public License version 2 as published by the Free Software ** Foundation and appearing in the file gpl-2.0.txt included in the ** packaging of this file. ** ** This program is distributed in the hope that it will be useful, ** but WITHOUT ANY WARRANTY; without even the implied warranty of ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ** GNU General Public License for more details. ** ** You should have received a copy of the GNU General Public License ** along with this program; if not, write to the Free Software ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ** ** This copyright notice MUST APPEAR in all copies of the script! ** **********************************************************************/ #include "main.h" #include <qapplication.h> #include <QSplashScreen> QSplashScreen *splash; #ifdef RS_SCRIPTING #include <qsproject.h> #endif #include "rs_fontlist.h" #include "rs_patternlist.h" #include "rs_scriptlist.h" #include "rs_settings.h" #include "rs_system.h" #include "rs_fileio.h" #include "rs_filtercxf.h" #include "rs_filterdxf.h" #include "rs_filterdxf1.h" #include "rs_filterlff.h" #include "qg_dlginitial.h" #include "qc_applicationwindow.h" #ifndef QC_SPLASH_TXTCOL # define QC_SPLASH_TXTCOL Qt::black #endif // for image mime resources from png files extern void QINITIMAGES_LIBRECAD(); #ifdef RS_SCRIPTING // extern void qInitImages_LibreCAD(); #endif #ifdef QC_BUILTIN_STYLE extern void applyBuiltinStyle(); #endif /** * Main. Creates Application window. * * Cleaning up #defines. */ int main(int argc, char** argv) { RS_DEBUG->setLevel(RS_Debug::D_WARNING); RS_DEBUG->print("param 0: %s", argv[0]); QCoreApplication::setApplicationName(XSTR(QC_APPNAME)); QCoreApplication::setApplicationVersion(XSTR(QC_VERSION)); QApplication app(argc, argv); // for image mime resources from png files // TODO: kinda dirty to call that explicitly QINITIMAGES_LIBRECAD(); #ifdef RS_SCRIPTING // qInitImages_librecad(); #endif for (int i=0; i<app.argc(); i++) { if (QString("--debug") == app.argv()[i]) { RS_DEBUG->setLevel(RS_Debug::D_DEBUGGING); } } QFileInfo prgInfo( QFile::decodeName(argv[0]) ); QString prgDir(prgInfo.dirPath(true)); RS_SETTINGS->init(XSTR(QC_COMPANYKEY), XSTR(QC_APPKEY)); RS_SYSTEM->init(XSTR(QC_APPNAME), XSTR(QC_VERSION), XSTR(QC_APPDIR), prgDir); RS_FILEIO->registerFilter(new RS_FilterLFF()); RS_FILEIO->registerFilter(new RS_FilterCXF()); RS_FILEIO->registerFilter(new RS_FilterDXF()); RS_FILEIO->registerFilter(new RS_FilterDXF1()); // parse command line arguments that might not need a launched program: QStringList fileList = handleArgs(argc, argv); QString lang; QString langCmd; QString unit; RS_SETTINGS->beginGroup("/Defaults"); #ifndef QC_PREDEFINED_UNIT unit = RS_SETTINGS->readEntry("/Unit", "Invalid"); #else unit = RS_SETTINGS->readEntry("/Unit", QC_PREDEFINED_UNIT); #endif RS_SETTINGS->endGroup(); // show initial config dialog: if (unit=="Invalid") { RS_DEBUG->print("main: show initial config dialog.."); QG_DlgInitial di(NULL); di.setText("<font size=\"+1\"><b>Welcome to " XSTR(QC_APPNAME) "</b></font>" "<br>" "Please choose the unit you want to use for new drawings and your " "preferred language.<br>" "You can changes these settings later in the " "Options Dialog of " XSTR(QC_APPNAME) "."); QPixmap pxm(":/main/intro_librecad.png"); di.setPixmap(pxm); if (di.exec()) { RS_SETTINGS->beginGroup("/Defaults"); unit = RS_SETTINGS->readEntry("/Unit", "None"); RS_SETTINGS->endGroup(); } RS_DEBUG->print("main: show initial config dialog: OK"); } #ifdef QSPLASHSCREEN_H RS_DEBUG->print("main: splashscreen.."); QPixmap* pixmap = new QPixmap(":/main/splash_librecad.png"); # endif RS_DEBUG->print("main: init fontlist.."); RS_FONTLIST->init(); RS_DEBUG->print("main: init fontlist: OK"); RS_DEBUG->print("main: init patternlist.."); RS_PATTERNLIST->init(); RS_DEBUG->print("main: init patternlist: OK"); RS_DEBUG->print("main: init scriptlist.."); RS_SCRIPTLIST->init(); RS_DEBUG->print("main: init scriptlist: OK"); RS_DEBUG->print("main: loading translation.."); RS_SETTINGS->beginGroup("/Appearance"); #ifdef QC_PREDEFINED_LOCALE lang = RS_SETTINGS->readEntry("/Language", ""); if (lang.isEmpty()) { lang=QC_PREDEFINED_LOCALE; RS_SETTINGS->writeEntry("/Language", lang); } langCmd = RS_SETTINGS->readEntry("/LanguageCmd", ""); if (langCmd.isEmpty()) { langCmd=QC_PREDEFINED_LOCALE; RS_SETTINGS->writeEntry("/LanguageCmd", langCmd); } #else lang = RS_SETTINGS->readEntry("/Language", "en"); langCmd = RS_SETTINGS->readEntry("/LanguageCmd", "en"); #endif RS_SETTINGS->endGroup(); RS_SYSTEM->loadTranslation(lang, langCmd); RS_DEBUG->print("main: loading translation: OK"); #ifdef QSPLASHSCREEN_H splash = new QSplashScreen(*pixmap); splash->show(); splash->message(QObject::tr("Loading.."), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); RS_DEBUG->print("main: splashscreen: OK"); #endif //QApplication::setStyle(new QWindowsStyle()); //QApplication::setStyle(new QPlatinumStyle()); #ifdef QC_BUILTIN_STYLE //js: RS_DEBUG->print("main: applying built in style.."); applyBuiltinStyle(); #endif RS_DEBUG->print("main: creating main window.."); QC_ApplicationWindow * appWin = new QC_ApplicationWindow(); RS_DEBUG->print("main: setting caption"); appWin->setCaption(XSTR(QC_APPNAME)); RS_DEBUG->print("main: show main window"); appWin->show(); RS_DEBUG->print("main: set focus"); appWin->setFocus(); RS_DEBUG->print("main: creating main window: OK"); #ifdef QSPLASHSCREEN_H if (splash) { RS_DEBUG->print("main: updating splash.."); splash->message(QObject::tr("Loading..."), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); RS_DEBUG->print("main: processing events"); qApp->processEvents(); RS_DEBUG->print("main: updating splash: OK"); } #endif // Set LC_NUMERIC so that enetring numeric values uses . as teh decimal seperator setlocale(LC_NUMERIC, "C"); RS_DEBUG->print("main: loading files.."); bool files_loaded = false; for (QStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it ) { #ifdef QSPLASHSCREEN_H if (splash) { splash->message(QObject::tr("Loading File %1..") .arg(QDir::convertSeparators(*it)), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); qApp->processEvents(); } #endif appWin->slotFileOpen(*it, RS2::FormatUnknown); files_loaded = true; } RS_DEBUG->print("main: loading files: OK"); #ifdef QSPLASHSCREEN_H # ifndef QC_DELAYED_SPLASH_SCREEN if (splash) { splash->finish(appWin); delete splash; splash = 0; } # endif delete pixmap; #endif //app.connect(&app, SIGNAL(lastWindowClosed()), &app, SLOT(quit())); RS_DEBUG->print("main: app.exec()"); if (!files_loaded) { appWin->slotFileNew(); } appWin->slotRunStartScript(); int r = app.exec(); RS_DEBUG->print("main: Temporary disabled delete appWin"); // delete appWin; RS_DEBUG->print("main: finished"); return r; } /** * Handles command line arguments that might not require a GUI. * * @return list of files to load on startup. */ QStringList handleArgs(int argc, char** argv) { RS_DEBUG->print("main: handling args.."); QStringList ret; bool doexit = false; QString machine; QString input; QString output; for (int i=1; i<argc; i++) { if (QString(argv[i]).startsWith("-")==false) { QString fname = QDir::convertSeparators( QFileInfo(QFile::decodeName(argv[i])).absFilePath() ); ret.append(fname); } else if (QString(argv[i])=="--exit") { doexit = true; } } if (doexit) { exit(0); } RS_DEBUG->print("main: handling args: OK"); return ret; } 给出完整代码的注释
最新发布
07-04
<think>我们面对的是LibreCAD项目的main.cpp文件,需要为其添加详细的中文注释。代码功能概述:该文件是LibreCAD应用程序的入口点,负责初始化应用程序、加载资源、处理命令行参数、显示初始配置对话框、创建主窗口并启动事件循环。我们将按照代码顺序逐段添加注释,解释每个部分的作用。注意:原始代码中已经有一些注释,我们将保留并补充更详细的说明。由于代码较长,我们将分块进行注释。第一步:包含头文件第二步:全局变量声明(如splash屏幕)第三步:main函数第四步:handleArgs函数此外,我们还需要注意一些预处理指令(如条件编译)的作用。开始注释:</think>以下是针对LibreCAD项目的`main.cpp`文件添加的详细中文注释,帮助理解代码功能和结构: ```cpp /**************************************************************************** ** 文件说明:LibreCAD主程序入口文件 ** 版权所有: ** - Copyright (C) 2010 R. van Twisk ** - Copyright (C) 2001-2003 RibbonSoft ** 许可协议:遵循GNU GPL v2许可(详见gpl-2.0.txt) ** 重要提示:此版权声明必须在所有副本中出现 **********************************************************************/ #include "main.h" // 主程序头文件 #include <qapplication.h> // Qt应用程序核心类 #include <QSplashScreen> // 启动画面支持 QSplashScreen *splash; // 全局启动画面指针 #ifdef RS_SCRIPTING // 脚本支持宏 #include <qsproject.h> // Qt脚本支持 #endif // LibreCAD核心模块 #include "rs_fontlist.h" // 字体列表管理 #include "rs_patternlist.h" // 填充图案管理 #include "rs_scriptlist.h" // 脚本管理 #include "rs_settings.h" // 配置管理 #include "rs_system.h" // 系统初始化 #include "rs_fileio.h" // 文件I/O接口 #include "rs_filtercxf.h" // CXF文件过滤器 #include "rs_filterdxf.h" // DXF文件过滤器 #include "rs_filterdxf1.h" // DXFv1文件过滤器 #include "rs_filterlff.h" // LFF文件过滤器 // 界面组件 #include "qg_dlginitial.h" // 初始配置对话框 #include "qc_applicationwindow.h" // 主应用窗口 // 启动画面文本颜色定义 #ifndef QC_SPLASH_TXTCOL # define QC_SPLASH_TXTCOL Qt::black #endif // 图像资源初始化函数声明 extern void QINITIMAGES_LIBRECAD(); #ifdef QC_BUILTIN_STYLE extern void applyBuiltinStyle(); // 内置样式应用函数 #endif /** * 主函数 - LibreCAD入口点 * @param argc 命令行参数数量 * @param argv 命令行参数数组 * @return 应用程序退出代码 */ int main(int argc, char** argv) { // 初始化调试系统(默认警告级别) RS_DEBUG->setLevel(RS_Debug::D_WARNING); RS_DEBUG->print("param 0: %s", argv[0]); // 设置应用程序元数据 QCoreApplication::setApplicationName(XSTR(QC_APPNAME)); QCoreApplication::setApplicationVersion(XSTR(QC_VERSION)); // 创建Qt应用程序实例 QApplication app(argc, argv); // 初始化图像资源(PNG文件) QINITIMAGES_LIBRECAD(); // 处理调试参数(如--debug) for (int i=0; i<app.argc(); i++) { if (QString("--debug") == app.argv()[i]) { RS_DEBUG->setLevel(RS_Debug::D_DEBUGGING); } } // 获取程序路径并初始化系统 QFileInfo prgInfo(QFile::decodeName(argv[0])); QString prgDir(prgInfo.dirPath(true)); RS_SETTINGS->init(XSTR(QC_COMPANYKEY), XSTR(QC_APPKEY)); RS_SYSTEM->init(XSTR(QC_APPNAME), XSTR(QC_VERSION), XSTR(QC_APPDIR), prgDir); // 注册文件过滤器 RS_FILEIO->registerFilter(new RS_FilterLFF()); // LFF格式 RS_FILEIO->registerFilter(new RS_FilterCXF()); // CXF格式 RS_FILEIO->registerFilter(new RS_FilterDXF()); // DXF格式 RS_FILEIO->registerFilter(new RS_FilterDXF1()); // DXFv1格式 // 处理命令行参数并获取文件列表 QStringList fileList = handleArgs(argc, argv); // 读取配置(语言和单位) QString lang, langCmd, unit; RS_SETTINGS->beginGroup("/Defaults"); #ifndef QC_PREDEFINED_UNIT unit = RS_SETTINGS->readEntry("/Unit", "Invalid"); #else unit = RS_SETTINGS->readEntry("/Unit", QC_PREDEFINED_UNIT); #endif RS_SETTINGS->endGroup(); // 首次运行时显示初始配置对话框 if (unit == "Invalid") { QG_DlgInitial di(NULL); di.setText("<font size=\"+1\"><b>欢迎使用 " XSTR(QC_APPNAME) "</b></font>" "<br>" "请为新图纸选择单位和首选语言<br>" "您稍后可在选项对话框中修改这些设置"); QPixmap pxm(":/main/intro_librecad.png"); di.setPixmap(pxm); if (di.exec()) { RS_SETTINGS->beginGroup("/Defaults"); unit = RS_SETTINGS->readEntry("/Unit", "None"); RS_SETTINGS->endGroup(); } } // 初始化资源系统 #ifdef QSPLASHSCREEN_H QPixmap* pixmap = new QPixmap(":/main/splash_librecad.png"); // 启动画面图片 #endif RS_FONTLIST->init(); // 初始化字体列表 RS_PATTERNLIST->init(); // 初始化填充图案 RS_SCRIPTLIST->init(); // 初始化脚本 // 加载本地化翻译 RS_SETTINGS->beginGroup("/Appearance"); #ifdef QC_PREDEFINED_LOCALE lang = RS_SETTINGS->readEntry("/Language", ""); if (lang.isEmpty()) { lang = QC_PREDEFINED_LOCALE; RS_SETTINGS->writeEntry("/Language", lang); } langCmd = RS_SETTINGS->readEntry("/LanguageCmd", ""); if (langCmd.isEmpty()) { langCmd = QC_PREDEFINED_LOCALE; RS_SETTINGS->writeEntry("/LanguageCmd", langCmd); } #else lang = RS_SETTINGS->readEntry("/Language", "en"); langCmd = RS_SETTINGS->readEntry("/LanguageCmd", "en"); #endif RS_SETTINGS->endGroup(); RS_SYSTEM->loadTranslation(lang, langCmd); // 加载翻译文件 // 显示启动画面 #ifdef QSPLASHSCREEN_H splash = new QSplashScreen(*pixmap); splash->show(); splash->message(QObject::tr("加载中.."), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); #endif // 应用内置样式(如果启用) #ifdef QC_BUILTIN_STYLE applyBuiltinStyle(); #endif // 创建并显示主窗口 QC_ApplicationWindow* appWin = new QC_ApplicationWindow(); appWin->setCaption(XSTR(QC_APPNAME)); // 设置窗口标题 appWin->show(); // 显示窗口 appWin->setFocus(); // 设置焦点 // 设置LC_NUMERIC区域(确保数字格式一致) setlocale(LC_NUMERIC, "C"); // 加载命令行指定的文件 bool files_loaded = false; for (QStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it) { #ifdef QSPLASHSCREEN_H if (splash) { splash->message(QObject::tr("加载文件 %1..") .arg(QDir::convertSeparators(*it)), Qt::AlignRight|Qt::AlignBottom, QC_SPLASH_TXTCOL); qApp->processEvents(); // 更新UI } #endif appWin->slotFileOpen(*it, RS2::FormatUnknown); // 打开文件 files_loaded = true; } // 清理启动画面 #ifdef QSPLASHSCREEN_H #ifndef QC_DELAYED_SPLASH_SCREEN if (splash) { splash->finish(appWin); delete splash; splash = nullptr; } #endif delete pixmap; #endif // 如果没有加载文件则创建新文档 if (!files_loaded) { appWin->slotFileNew(); } // 运行启动脚本 appWin->slotRunStartScript(); // 启动事件循环 int r = app.exec(); // 清理资源(主窗口清理被临时禁用) // delete appWin; return r; } /** * 处理命令行参数 * @param argc 参数数量 * @param argv 参数数组 * @return 需要加载的文件列表 */ QStringList handleArgs(int argc, char** argv) { QStringList ret; // 返回的文件列表 bool doexit = false; // 退出标志 // 遍历命令行参数 for (int i = 1; i < argc; i++) { // 非选项参数视为文件名 if (!QString(argv[i]).startsWith("-")) { QString fname = QDir::convertSeparators( QFileInfo(QFile::decodeName(argv[i])).absFilePath()); ret.append(fname); } // 处理退出选项 else if (QString(argv[i]) == "--exit") { doexit = true; } } // 立即退出(不启动GUI) if (doexit) { exit(0); } return ret; } ``` ### 关键功能说明 1. **初始化流程**: - 设置应用程序元数据(名称/版本) - 初始化调试系统和配置管理 - 注册文件格式过滤器(DXF/CXF/LFF) - 处理命令行参数[^1] 2. **首次运行配置**: - 通过`QG_DlgInitial`显示单位和语言选择对话框 - 保存用户偏好到`RS_SETTINGS` 3. **资源加载**: - 字体/图案/脚本列表初始化 - 本地化翻译加载(`loadTranslation`) - 启动画面显示(`QSplashScreen`) 4. **主窗口创建**: - 实例化`QC_ApplicationWindow`主窗口 - 处理命令行指定的文件加载 - 执行启动脚本(`slotRunStartScript`) 5. **事件循环**: - 启动Qt事件循环(`app.exec()`) - 控制权移交至GUI系统 ### 设计特点 1. **模块化初始化**: ```cpp RS_FONTLIST->init(); // 字体 RS_PATTERNLIST->init(); // 图案 RS_SCRIPTLIST->init(); // 脚本 ``` 各资源系统独立初始化,便于扩展和维护[^1]。 2. **跨平台处理**: ```cpp setlocale(LC_NUMERIC, "C"); // 统一数字格式 ``` 确保不同区域设置下的数值解析一致性。 3. **条件编译**: ```cpp #ifdef RS_SCRIPTING #include <qsproject.h> #endif ``` 通过宏控制功能模块的编译包含。 4. **资源管理**: ```cpp extern void QINITIMAGES_LIBRECAD(); ``` 使用Qt资源系统(:/prefix)嵌入二进制资源。 ### 相关问题 1. LibreCAD如何处理不同DXF版本的兼容性问题?[^1] 2. 如何扩展LibreCAD支持新的文件格式? 3. 启动脚本(`slotRunStartScript`)通常用于执行哪些操作? 4. 在跨平台开发中,`setlocale(LC_NUMERIC, "C")`为何如此重要? 5. LibreCAD的翻译系统如何实现动态语言切换? [^1]: QCAD编译指南与架构参考
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值