QCad源码分析 第一章

   鉴于介绍Qcad相关的文章很少,决定写此博客,一来便于日后查找,二来要有分享精神。本文章基于Qcad3 .21.3.4的开源版本进行分析,分过程中难免有疏漏,如果有新的发现会及时更改,不足之处望高手指正,十分感谢。

   QCad是一款2维的cad软件,基于Qt类库开发,逻辑处理方面夹杂着QtScript,所以首先要熟悉javascript,js相关文章不在赘述,其次QtScript的使用方面,详细阅读Qt官方文档Qt Script。

    首先讲一下QCad软件中的简单启动过程,也就是代码中的main函数,QCad是一款跨平台的软件,暂时之讲解window平台的源码。

int main(int argc, char *argv[]) {
    qDebug() << "QCAD version " << R_QCAD_VERSION_STRING;
    // For correct Unicode translation, apply the current system locale:
    setlocale(LC_ALL, "");
    // But use usual conversion for scanf()/sprintf():
    setlocale(LC_NUMERIC, "C");

    // Finetuning Japanese encoding for correct DXF/DWG import.
    // see http://qt-project.org/doc/qt-4.8/codecs-jis.html
#ifdef Q_OS_WIN
    _putenv_s("UNICODEMAP_JP", "cp932");
#else
    setenv("UNICODEMAP_JP", "cp932", 1);
#endif

#ifdef Q_OS_WIN
#if QT_VERSION >= 0x050200
    // enable OpenGL logging under Windows
    // this info can then be shown in the about dialog
    QLoggingCategory::setFilterRules(QStringLiteral("qt.qpa.gl=true"));
#endif
#endif

    // Auto scale up user interface for high res displays under Windows:
#ifdef Q_OS_WIN
#if QT_VERSION >= 0x050600
    //_putenv_s("QT_SCALE_FACTOR", "auto");
    _putenv_s("QT_AUTO_SCREEN_SCALE_FACTOR", "1");
#else
    _putenv_s("QT_DEVICE_PIXEL_RATIO", "auto");
#endif
#endif

#ifdef Q_OS_MAC
    // TODO: fix linking with objective c
    removeMacMenus();
#endif

    // these are defaults:
    //添加组织、公司、版本信息
    qApp->setOrganizationName("QCAD");
    qApp->setOrganizationDomain("QCAD.org");
    qApp->setApplicationName("QCAD");
    qApp->setApplicationVersion(RSettings::getVersionString());

    //调试输出重定义
    RMainWindow::installMessageHandler();

#if QT_VERSION >= 0x050000
    //高像素比
    QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps);
#endif

#ifdef Q_OS_MAC
    // TODO: make available as script function:
    QCoreApplication::setAttribute(Qt::AA_DontShowIconsInMenus);

    if (QSysInfo::MacintoshVersion>=0x000B) {
        // system font change bug fix on OS X 10.9 (Mavericks):
        QFont::insertSubstitution(".Lucida Grande UI", "Lucida Grande");
    }
#endif

    //产生随机数
    QTime time = QTime::currentTime();
    qsrand((uint)time.msec());

    //设置原始参数到RSettings当中
    QStringList originalArguments;
    for (int i=0; i<argc; i++) {
        QString a = argv[i];
        originalArguments.append(a);
    }
    RSettings::setOriginalArguments(originalArguments);

    //得到应用程序的id,用于一个终端只能启用一个QCad程序
    QString appId = "QCAD";
    for (int i=0; i<argc; i++) {
        QString a = argv[i];
        if (a=="-app-id" && i+1<argc) {
            appId = argv[i+1];
        }
    }

    //是否启用帮助界面
    bool guiEnabled = true;
    for (int i=1; i<argc; i++) {
        if (!strcmp(argv[i], "-no-gui") || !strcmp(argv[i], "-help")) {
            //如果设置-no-gui或者-help参数,则不启用界面
            guiEnabled = false;
        }
    }

    //应用程序的派生类,派生主要用于一个终端只能启用一个QCad程序中的本地服务通信
    RSingleApplication* app = new RSingleApplication(appId, argc, argv, guiEnabled);

#if defined(Q_OS_MAC) || defined(Q_OS_LINUX)
    // note that SIGPIPE is only ignored in release mode, gdb catches SIGPIPE
    // by default. To disable that behavior in gdb, use:
    // handle SIGPIPE nostop noprint pass
    signal(SIGPIPE,catchSigPipe);
#endif

#ifdef Q_OS_MAC
    // activate Mac OS X dock icon if desired:
    if (!app->arguments().contains("-no-dock-icon") &&
            !app->arguments().contains("-help") && !app->arguments().contains("-h") &&
            !app->arguments().contains("-version") && !app->arguments().contains("-v")) {
        ProcessSerialNumber psn;
        if (GetCurrentProcess(&psn) == noErr) {
            TransformProcessType(&psn, kProcessTransformToForegroundApplication);
        }
    }
#endif
    if (!app->arguments().contains("-allow-multiple-instances")) {
        //如果进程不允许多实例
        // send arguments to running instance for further processing:
        if (app->sendMessage(app->arguments().join("\n"), 30000)) {
            qWarning("Application already running. Aborting...");
            return 0;
        }
    }

#ifdef Q_OS_WIN
    // SVG icons are only rendered if this line is present under windows:
    QImageReader::supportedImageFormats();

    // the SQLite plugin can only be loaded if this line is present under windows:
    QSqlDatabase::drivers();
#endif

    //注册RColor类型到元对象系统
    qRegisterMetaType<RColor>();
    //将RColor注册到流操纵当中去,RColor支持<<操作
    qRegisterMetaTypeStreamOperators<RColor>("RColor");

    //注册RVector类型到元对象系统
    qRegisterMetaType<RVector>();
    //将RColor注册到流操纵当中去,RVector支持<<操作
    qRegisterMetaTypeStreamOperators<RVector>("RVector");

    //获取当前路径
    QString cwd = QDir::currentPath();
    //设置发布路径
    RSettings::setLaunchPath(cwd);

    // set current working directory:
    //将应用程序所在的目录设为当前目录
    QDir::setCurrent(RSettings::getApplicationPath());

    // disable Qt library paths to avoid plugins for Qt designer from being found:
    QStringList pluginPaths = RSettings::getPluginPaths();
    if (pluginPaths.isEmpty()) {
        qWarning() << "No plugin paths found";
        return -1;
    }
    //设置库路径,查找dll时将在此目录下查找
    app->setLibraryPaths(pluginPaths);
    //数学库
    RMath::init();
    //加载字体
    RFontList::init();
    //加载填充图形
    RPatternListMetric::init();
    RPatternListImperial::init();

    // init object properties:
    //初始化对象属性id
    RObject::init();
    REntity::init();
    RDocumentVariables::init();

    RArcEntity::init();
    RBlockReferenceEntity::init();
    RCircleEntity::init();
    RDimensionEntity::init();
    RDimLinearEntity::init();
    RDimAlignedEntity::init();
    RDimAngularEntity::init();
    RDimAngular2LEntity::init();
    RDimAngular3PEntity::init();
    RDimArcLengthEntity::init();
    RDimDiametricEntity::init();
    RDimOrdinateEntity::init();
    RDimRadialEntity::init();
    RDimRotatedEntity::init();
    REllipseEntity::init();
    RImageEntity::init();
    RHatchEntity::init();
    RLeaderEntity::init();
    RLineEntity::init();
    RPointEntity::init();
    RPolylineEntity::init();
    RSolidEntity::init();
    RTraceEntity::init();
    RFaceEntity::init();
    RSplineEntity::init();
    RXLineEntity::init();
    RRayEntity::init();
    RViewportEntity::init();

    RTextBasedEntity::init();
    RTextEntity::init();
    RAttributeDefinitionEntity::init();
    RAttributeEntity::init();

    RUcs::init();
    RLayer::init();
    RLayout::init();
    RLinetype::init();
    RBlock::init();
    RView::init();

    // make sure plugins can find plugin related settings:
    // these are always stored in "QCAD3.ini/conf":
    //重载应用程序名称【】
    RSettings::setApplicationNameOverride("QCAD3");
    //插件管理类
    RPluginLoader::loadPlugins(true);
    //初始化线型文件
    RLinetypeListMetric::init();
    RLinetypeListImperial::init();

    // check for autostart option:
    //检查自动脚本选项
    QString autostartFile;
    //获取参数列表,并从参数列表中查找是否有启动的脚本文件
    QStringList arguments = app->arguments();
    int i = arguments.indexOf("-autostart");
    if (i!=-1 && arguments.count()>i+1) {
        autostartFile = arguments.at(i+1);
    }

    //将脚本的工厂函数和脚本类型注册到系统当中,【jsfactory--js, pytonfactory--python】
    RScriptHandlerRegistry::registerScriptHandler(RScriptHandlerEcma::factory,
            RScriptHandlerEcma::getSupportedFileExtensionsStatic());
    //通过脚本工厂【jsfactory】创建具体的脚本类
    RScriptHandler* handler = RScriptHandlerRegistry::getGlobalScriptHandler("js");
    Q_ASSERT(handler!=NULL);
    //初始化自动脚本程序【初始化过程中会创建主界面】
    handler->init(autostartFile, arguments.mid(i+1));

    //如果脚本初始化过程中出现异常,则返回
    int ret = 0;
    if (handler->hasUncaughtExceptions()) {
        ret = 1;
    }

    // delete script handler and print uncaught exceptions:
    //删除脚本句柄,打印异常
    delete handler;

    
    RPluginLoader::unloadPlugins();

    RSettings::uninit();
    RFontList::uninit();
    RPatternListMetric::uninit();
    RPatternListImperial::uninit();
    RSingleton::cleanUp();
    RMath::uninit();

    RDocumentInterface::deleteClipboard();

    //RDebug::printCounters();

    return ret;
}

 

  • 11
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: QCAD源码编译过程中没有生成qcad.exe的原因可能有以下几种: 1. 编译过程中出现了错误或警告:在编译源码的过程中,可能会出现一些错误或警告信息,这些问题可能会导致生成的可执行文件不存在。需要检查编译过程中的日志信息,查找并解决出现的错误。 2. 编译配置问题:在进行源码编译时,可能需要进行一些配置操作,例如指定生成的可执行文件的名称、路径等。如果配置不正确,可能导致生成的可执行文件不存在。需要仔细检查编译配置,确保生成的可执行文件的相关设置正确无误。 3. 缺少依赖项:在编译源码时,可能需要依赖一些第三方库或工具。如果缺少了这些依赖项,可能会导致生成的可执行文件不存在。需要查看编译过程中的依赖项信息,确保所有依赖项都已正确安装并配置。 4. 操作系统兼容性问题:有些情况下,源码可能只能在特定的操作系统上编译成功。如果您的操作系统与源码不兼容,可能无法生成可执行文件。需要确认您的操作系统是否符合源码的兼容要求,如果不符合,可能需要考虑更换操作系统或寻找适应您当前环境的其他解决方案。 综上所述,QCAD源码编译没有生成qcad.exe可能是由于编译过程中的错误、配置问题、缺少依赖项或操作系统兼容性等原因所致。您可以详细检查编译过程中的日志信息、编译配置、依赖项安装以及操作系统兼容性,以解决生成qcad.exe的问题。 ### 回答2: QCAD是一个开源的计算机辅助设计(CAD)软件,使用C++语言编写。为了编译QCAD源码并生成可执行文件(qcad.exe),您需要按照以下步骤进行操作: 1. 首先,确保您的计算机已经安装了适当的开发环境,如GCC编译器、CMake和Qt开发工具包。 2. 下载QCAD源码压缩包,可以从QCAD的官方网站或者GitHub仓库获取。 3. 解压源码压缩包到您选择的目录中。 4. 打开命令行终端,并导航到源码目录。 5. 创建一个新的文件夹,用于存储生成的可执行文件。 6. 在命令行中输入以下命令来配置编译过程: ```shell cmake -G "Unix Makefiles" -DCMAKE_INSTALL_PREFIX=/path/to/qcad_executable_directory . ``` 这将使用Unix Makefiles生成器配置构建过程,并指定编译后的文件存储路径。 7. 一旦配置完成,使用以下命令进行编译: ```shell make ``` 这将开始编译源码,并生成可执行文件。编译时间可能会有所不同,具体取决于您的计算机性能和源码规模。 8. 编译完成后,在指定的保存路径下应该会生成一个名为qcad.exe的可执行文件。 如果在编译过程中出现错误或警告,请检查您的环境设置和依赖项,可能需要解决一些缺失的库或依赖关系。同时,确保按照官方文档提供的编译指南进行操作。 ### 回答3: QCAD源码编译生成的可执行文件qcad.exe可能没有成功生成的原因有以下几点: 1. 编译过程中出现错误:在编译源码的过程中,可能会因为各种原因导致编译错误,比如缺少依赖库、编译选项设置错误等。这些错误会中断编译过程,导致最终的可执行文件没有生成。需要仔细检查编译日志或错误信息,解决相关编译错误。 2. 缺少构建环境:在编译QCAD源码之前,需要确定是否已经安装了编译所需的构建环境和工具链。这包括编译器、构建系统(如CMake)、相关依赖库等。如果缺少必要的构建环境,编译过程将无法进行或无法正确完成,因此不会生成可执行文件。 3. 编译选项未正确设置:编译过程中需要设置相应的编译选项,以配置编译器、链接选项和依赖库等。如果编译选项设置不正确,可能导致编译过程中的错误或生成的可执行文件出错。需要确认编译选项的设置是否正确。 4. 缺少构建目标:在进行源码编译时,需要指定正确的编译目标。如果没有正确指定目标,编译系统将无法找到生成可执行文件的相关源码文件,并最终没有生成qcad.exe。 针对这些可能的原因,我们需要逐个排查和解决。通过仔细检查编译日志、确认构建环境和工具链的安装情况、修正编译选项以及检查是否正确指定了构建目标,可以解决未生成qcad.exe的问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值