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

Qt编程的禁忌和限制 – moc应该这样用

 
阅读更多

这个题目乍一听起来有股冷飕飕的味道, 呵呵, 别想歪了, 纯粹和封建迷信无关哦。 笔者也是无意中发现在Qt的文档里有一篇关于moc工具的limitation的文章,里头的东西让笔者还挺惊讶的, 撰文以memo。

起因是qt群里有人问一个链接的错误, 程序结构很简单, 就是designer设计主界面,在代码里用多重继承方式使用, 奇怪的错误信息如下:

moc_mainwin.cpp:39: error: ‘staticMetaObject’ is not a member of ‘Ui::MainWindow’
moc_mainwin.cpp: In member function ‘virtual void* MainWin::qt_metacast(const char*)’: moc_mainwin.cpp:56: error: ‘qt_metacast’ is not a member of ‘MainWin::qt_metacast(const char*)::QMocSuperClass’
moc_mainwin.cpp: In member function ‘virtual int MainWin::qt_metacall(QMetaObject::Call, int, void**)’: moc_mainwin.cpp:62: error: ‘qt_metacall’ is not a member of ‘MainWin::qt_metacall(QMetaObject::Call, int, void**)::QMocSuperClass’
make: *** [moc_mainwin.o] Error 1

Qt自动生成的moc文件竟然也会编译出错?这可真有点匪夷所思。 笔者把工程拿过来从头看到尾也没有看出任何错误可能会导致这个链接错误。 N长时间后,一个编译阶段报出的warning引起了笔者注意, 大意是说多重继承不能从两个QObject类继承, 这就怪了,它怎么会把我的UI类也当成是从QObject派生的呢? 有了这个提示,笔者尝试着修改多重继承的那行代码:

class MainWin: public Ui::MainWindow, public QWidget

改为

class MainWin: public QWidget, public Ui::MainWindow

结果你猜怎么着?奇迹发生了……呵呵,编译成功!原来竟然是继承的顺序造成的问题。 莫非这是Qt的bug?

给trolltech support发bug report得到了这样的回答:

This is actually a known limitation which has been documented for some time, when using multiple inheritance you have to specify the QObject based class first and then the other class. Its mentioned in the documentation at:

http://doc.trolltech.com/4.5/moc.html

under the limitations section.

原来如彼! 看来咱的道行还不够,这么重要的文档竟然从来都不知道它的存在。

仔细阅读一下居然发现还有不少Qt中和moc相关的编程限制需要我们注意, 各位看官也来受受再教育吧:

moc的功能数一数

1、处理Q_OBJECT宏和signals/slots关键字,生成信号和槽的底层代码

2、处理Q_PROPERTY()和Q_ENUM()生成property系统代码

3、处理Q_FLAGS()和Q_CLASSINFO()生成额外的类meta信息

4、不需要moc处理的代码可以用预定义的宏括起来,如下:

#ifndef Q_MOC_RUN

#endif

moc的限制数一数(太多了,眼花缭乱)

1、模板类不能使用信号/槽机制

2、moc不扩展宏,所以信号和槽的定义不能使用宏, 包括connect的时候也不能用宏做信号和槽的名字以及参数

3、从多个类派生时,QObject派生类必须放在第一个, 因为moc是这么认为的…(比较流氓) 这也是我们前面的例子触犯的天条

4、函数指针不能作为信号或槽的参数, 因为其格式比较复杂,moc处理不了。 但可以用typedef把它定义成简单的形式再使用。(这招可真够绝的)

5、用枚举类型或typedef的类型做信号和槽的参数时,必须fully qualified。 这个词中文不知道怎么翻译才合适,简单的说就是, 如果是在类里定义的, 必须把类的路径或者命名空间的路径都加上, 防止出现混淆。 如Qt::Alignment之类的,前面的Qt就是Alignment的qualifier, 必须加上,而且有几级加几级。

6、信号和槽不能返回引用类型

7、signals和slots关键字区域只能放置信号和槽的定义,不能放其它的如变量定义等

呵呵,这些限制条款感觉颇像不平等条约, 是不是让你大开眼界了呢? 其实这些限制有一部分应该当作bug来论处, 只是对Qt编程影响不算太大,可暂时忽略,所以被归入优先级很低的问题处理了(意思就是可能永远都不改了)。

qt文档中还有一篇关于Qt为什么没有用模板来实现信号和槽的分析文章, 也是一篇有意思的科普读物, 推荐e文好的去看看。http://doc.trolltech.com/4.5/templates.html

分享到:
评论

相关推荐

    QT5编程入门,高清,有目录

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。2008年,Qt Company科技被诺基亚公司收购,Qt也因此成为诺基亚旗下...

    Qt MOC处理器 UML图

    对Qt MOC的源码 UML图

    使用Qt开发界面程序控制GPIO

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(MetaObjectCompiler,moc))以及一些宏,易于扩展,允许组件编程。2008年,奇趣科技被诺基亚公司收购,QT也因此成为诺基亚旗下的编程语言工具。2012年...

    qt项目开发实例超详细版

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。 本教程是qt项目开实例的详细介绍,很值得学习。

    QT项目开发实例

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。2008年,Qt Company科技被诺基亚公司收购,Qt也因此成为诺基亚...

    QT_connect函数的用法

    信号和槽机制是 QT 的核心机制,要精通 QT 编程就必须对信号和槽有所了解。信号和槽是一种高级接口,应用于对象之间的通信,它是 QT 的核心特性,也是 QT 区别于其它工具包的重要地方。信号和槽是 QT 自行定义的一种...

    CppMocTest.7z

    Q_OBJECT 为QObject 对象提供了信号与槽的基础,如果我们需要使用信号与槽,最简单方便的方式就是继承QObject,并在类开头放置Q_OBJECT 这个宏,在预编译前moc 会自动扫描所有头文件,根据 signals 和 slot 关键字,...

    qt5-qt平台的使用.pdf

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。2008年,Qt Company科技被诺基亚公司收购,Qt也因此成为诺基亚...

    qt5入门 文档

    架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些 宏,易于扩展,允许组件编程。2008年,奇趣科技被诺基亚公司收购,QT也因此成为诺基 亚旗下的编程语言工具。2012年,Qt被Digia...

    在qt中使用libXL

    LibXL是一个可以读写Excel文件的库。它不需要Microsoft Excel和。net框架,结合了易于使用和强大的功能,获取key:https://blog.csdn.net/qq_43445867/article/details/132572402

    vs2019+QT开发的传感器界面

    vs2019+QT开发的传感器界面

    C++ Qt5 范例开发大全

    详细的介绍了QT5的使用,《C++ Qt5 范例开发大全》Qt 是 1991 年由奇趣科技开发的跨平台 C++图形用户界面应用程序开发框架。它既可以 开发 GUI 程式,也可用于开发非 GUI 程式,比如控制台工具和服务器。Qt 是面向...

    基于QT平台的手持媒体播放器项目实战

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,易于扩展,允许 组件编程。2008年,奇趣科技被诺基亚公司收购,QT也因此成为诺基亚旗下的编程语言工具。...

    qt翻页按钮控件及示例.rar

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。 2008年,Qt Company科技被诺基亚公司收购,Qt也因此成为诺基亚...

    QT写的登录界面

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。2008年,Qt Company科技被诺基亚公司收购,Qt也因此成为诺基亚...

    qt-opensource

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,易于扩展,允许组件编程。2008年,奇趣科技被诺基亚公司收购,QT也因此成为诺基亚旗下的编程语言工具。...

    Qt基础学习笔记

    Qt是面向对象的框架,使用特殊的代码生成扩展(称为元对象编译器(Meta Object Compiler, moc))以及一些宏,Qt很容易扩展,并且允许真正地组件编程。2008年,Qt Company科技被诺基亚公司收购,Qt也因此成为诺基亚...

    基于C++ &QT的学生选课系统.zip

    Qt本身并不是一种编程语言,它本质上是一个跨平台的C++开发类库,是用标准C++编写的类库,它为开发GUI应用程序和非GUI应用程序提供了各种类。 Qt对标准C++进行了扩展,引入了一些新概念和功能,例如信号和槽、对象...

Global site tag (gtag.js) - Google Analytics