`
gaofen100
  • 浏览: 1243315 次
文章分类
社区版块
存档分类
最新评论

Qt 之实用程序 moc 学习

 
阅读更多

本文关注Qt的工具程序 moc 本身。

moc : 元对象编译器(Meta-Object Compiler)

命令行选项

moc -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED hled.h -o moc_hled.cpp

运行moc-h或者查看Manual关注几个选项:

-I<dir>

add dir to the include path for header files

-E

preprocess only; do not generate meta object code

-D<macro>[=<def>]

define macro, with optional definition

-U<macro>

undefine macro

-i

do not generate an #include statement

-p<path>

path prefix for included file

-f[<file>]

force #include, optional file name

其中:

  • -D-U

    • 定义和反定义宏, (注:内部默认定义Q_MOC_RUN__cplusplus两个宏)

  • -i-f

    • 控制是否包含include语句,默认是自动(对比Q_OBJECT这个宏分别出现在*.h和*.cpp时生成的文件的不同)

moc 的处理分两个阶段(共3个步骤):

  • Preprocessor
  • Moc
    • parse
    • generate

    Preprocessor pp;
    Moc moc;
    pp.macros["Q_MOC_RUN"];
    pp.macros["__cplusplus"];
...
    // 1. preprocess
    moc.symbols = pp.preprocessed(moc.filename, in);
    fclose(in);

    if (!pp.preprocessOnly) {
        // 2. parse
        moc.parse();
    }

    // 3. and output meta object code
    if (pp.preprocessOnly) {
        fprintf(out, "%s\n", composePreprocessorOutput(moc.symbols).constData());
    } else {
        moc.generate(out);
    }

词法分析

lexical analysis

moc 将输入文件解析成一个 Token (即symbols) 的列表

moc.symbols = pp.preprocessed(moc.filename, in);

词法分析的基础是一个有限状态机(fix me?),源码位于 $QTDIR/src/tools/moc 下的

  • keywords.cpp
  • ppkeywords.cpp

这两个文件是由$QTDIR/src/tools/moc/util下的工具程序生成的,generate_keywords.cpp 文件中是原始的(可读的) 关键词和Token的对应关系

...
    { "while", "WHILE" },
    { "do", "DO" },
    { "for", "FOR" },
    { "break", "BREAK" },
    { "continue", "CONTINUE" },
    { "goto", "GOTO" },
    { "return", "RETURN" },
    { "Q_OBJECT", "Q_OBJECT_TOKEN" },
    { "Q_GADGET", "Q_GADGET_TOKEN" },
    { "Q_PROPERTY", "Q_PROPERTY_TOKEN" },
    { "Q_ENUMS", "Q_ENUMS_TOKEN" },
    { "Q_FLAGS", "Q_FLAGS_TOKEN" },
    { "Q_DECLARE_FLAGS", "Q_DECLARE_FLAGS_TOKEN" },
    { "Q_DECLARE_INTERFACE", "Q_DECLARE_INTERFACE_TOKEN" },
...

语法分析(?)

在 Tokenization 之后,需要parse某些我们关注的Token,此时需要处理Token之间的关系。

moc.parse();

比如:对于 Q_DECLARE_METATYPE

void Moc::parseDeclareMetatype()
{
    next(LPAREN);
    QByteArray typeName = lexemUntil(RPAREN);
    typeName.remove(0, 1);
    typeName.chop(1);
    metaTypes.append(typeName);
}

对于 signals

void Moc::parseSignals(ClassDef *def)
{
    next(COLON);
    while (inClass(def) && hasNext()) {
...
        FunctionDef funcDef;
        funcDef.access = FunctionDef::Protected;
        parseFunction(&funcDef);
        if (funcDef.isVirtual)
            warning("Signals cannot be declared virtual");
        if (funcDef.inlineCode)
            error("Not a signal declaration");
        def->signalList += funcDef;
        while (funcDef.arguments.size() > 0 && funcDef.arguments.last().isDefault) {
            funcDef.wasCloned = true;
            funcDef.arguments.removeLast();
            def->signalList += funcDef;
        }
    }
}

output

moc.generate(out);

将metatype信息转换成代码并输出是通过另一个类来完成的:

    for (i = 0; i < classList.size(); ++i) {
        Generator generator(&classList[i], metaTypes, out);
        generator.generateCode();
    }

从类定义大致可以猜出它做了什么

class Generator
{
    FILE *out;
    ClassDef *cdef;
    QVector<uint> meta_data;
public:
    Generator(ClassDef *classDef, const QList<QByteArray> &metaTypes, FILE *outfile = 0);
    void generateCode();
    QMetaObject *generateMetaObject(bool ignoreProperties);
private:
    void generateClassInfos();
    void generateFunctions(QList<FunctionDef> &list, const char *functype, int type);
    void generateEnums(int index);
    void generateProperties();
    void generateMetacall();
    void generateStaticMetacall(const QByteArray &prefix);
    void generateSignal(FunctionDef *def, int index);
...

参考


分享到:
评论

相关推荐

    [大家网]Linux窗口程序设计—Qt4精彩实例分析

    ### Linux窗口程序设计—Qt4精彩实例分析 #### 核心知识点概述 本文将围绕Linux窗口程序设计中的Qt4框架进行...无论是初学者还是有一定经验的开发者,都能从Qt4中获得所需的工具和支持,创造出美观实用的应用程序。

    闵卫QT开发PPT

    另外,QT的 moc 工具负责处理元对象系统,确保信号和槽的正确连接。 QT的模块化设计也是其一大特点。例如,QNetworkAccessManager和QNetworkReply用于网络请求,QSqlDatabase和QSqlQuery用于数据库操作,QPainter和...

    qt快速入门

    综上所述,这份文档的目的是为初学者提供一个全面且实用的Qt快速入门指导,涵盖了从基础概念理解、开发环境搭建、核心编程知识学习到实际案例分析等各个方面。它不仅帮助初学者入门Qt开发,也为他们未来的学习和应用...

    Qt函数查询手册chm.zip

    同时,Qt的模棱两可(Q_OBJECT)宏和 moc 工具也是其独特之处,它们使得C++类能够支持信号和槽,以及其他元对象系统特性。在手册中,你会了解到如何在自定义类中正确使用Q_OBJECT,以及如何编写 moc 可识别的信号和...

    linux 下qt开发三角板

    在Linux环境下进行Qt开发,尤其是构建跨平台应用,是一个非常有趣且实用的技能。Qt是一个功能强大的C++图形用户界面库,它支持多种操作系统,包括Linux、Windows、macOS等。这个“linux下qt开发三角板”项目,显然是...

    关于mysql的qt编程

    通过这个项目,开发者不仅可以学习到如何使用Qt设计用户界面,还能掌握如何与MySQL数据库交互,同时了解在ARM开发板上运行和调试应用程序的技巧。这为构建嵌入式系统中的数据管理和可视化提供了实用的示例。

    QT creater教程

    在学习Qt的过程中,不仅要熟悉这些知识点,还要学会如何将它们组合起来构建实用的应用程序。对于初学者来说,理解基础概念是关键,随着学习的深入,逐渐接触更高级的主题,如自定义控件、动画、图形渲染等。通过大量...

    QT4.3.3 for VC6.0

    QT4.3.3 for VC6.0 是一个专为Visual C++ 6.0集成开发环境设计的Qt库版本。Qt是一个跨平台的应用程序开发...虽然现代开发通常转向更新的IDE和Qt版本,但这个资源对于某些特定场景下的软件开发依然具有很高的实用价值。

    基于Qt的嵌入式终端程序应用本科毕业设计——记事本与电子相册.doc

    基于Qt的嵌入式终端程序应用本科毕业设计——记事本与电子相册.doc 本文档主要讨论基于Qt的嵌入式终端程序应用设计和实现记事本和电子相册。下面是相关知识点的总结: 一、嵌入式系统设计 * 嵌入式系统是一种基于...

    QT whitepaper Web

    在Qt中,事件是应用程序与外部世界交互的主要方式之一。开发者可以通过发送特定类型的事件来触发应用程序中的行为。 ##### 11.2 事件传递 Qt通过事件队列机制来管理事件的传递过程。这意味着所有的事件都会先进入...

    Qt将Sqlite中的数据导出为Excel

    本篇我们将探讨如何利用Qt将SQLite数据库中的数据导出到Excel格式,这是一个实用的功能,尤其对于需要数据分析和报告的项目。 首先,让我们理解这个过程的基本步骤: 1. **连接SQLite数据库**:使用`QSqlDatabase`...

    QT_学习笔记widget,MainWindow和Dialog的选择使用.doc

    QT_学习笔记 widget,MainWindow 和 Dialog 的选择使用 下面是从给定的文件中生成的相关知识点: Qt 基础知识 * 在 Qt 中,每个类都有一个对应的同名头文件,其中包含其类定义。 * QApplication 类用于管理应用...

    Qt4图形设计与嵌入式开发.pdf

    - **怎样学习Qt**:提供了学习Qt的有效途径和建议,包括资源推荐、学习路径规划等。 - **Qt对象类模型**: - **信号与槽**:信号与槽机制是Qt框架的核心特性之一,它使得对象间通信变得简单高效。这部分讲解了...

    51CTO下载-Document-For-QT.docx

    学习Qt通常从编写第一个程序开始,如"Hello, Qt!"。这通常涉及以下步骤: 1. 引入必要的头文件,如`&lt;QApplication&gt;`和`&lt;QLabel&gt;`。 2. 定义主函数`main()`,创建`QApplication`实例,处理事件循环。 3. 创建`QLabel...

    Linux下神通QT集成环境搭建手册.pdf

    QT的面向对象特性使其可以方便地进行组件编程,同时其包含的元对象编译器(moc)和宏支持,极大地简化了组件的扩展和编程过程。为了适应不同平台的需求,QT提供了跨平台的集成开发环境(IDE)——QtCreator,这是一...

    VS C#调用QT Active控件demo

    3. **编译为ActiveX库**:使用Qt的moc工具和qmake编译Qt控件为ActiveX库。这一步会生成一个COM组件,可以在其他支持ActiveX的应用程序中使用。 4. **在VS中引用ActiveX控件**:在Visual Studio的C#项目中,添加对...

    Qt-Tutorial-_-elaborate-version.rar_qt 解释

    **Qt 框架详解教程** Qt 是一个跨平台的应用程序开发框架,广泛应用于桌面、移动设备和嵌入式系统的GUI(图形用户界面)开发。...通过深入学习和实践,你将能够利用Qt的强大功能,创建出功能丰富的跨平台应用程序。

    QT3连接SQLite

    MOC_DIR = .moc OBJECTS_DIR = .obj } TEMPLATE = app CONFIG += qt warn_on release LANGUAGE = C++ SQLITE_PATH = /usr/local/sqlite3 DEPENDPATH += $$SQLITE_PATH/include INCLUDEPATH += $$SQLITE_PATH/...

Global site tag (gtag.js) - Google Analytics