(转载)Qt中MOC的一些限制

无意中发现在Qt的文档里有一篇关于moc工具的limitation的文章,里头的东西值得学习一下。

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关键字区域只能放置信号和槽的定义,不能放其它的如变量定义等
  8. 呵呵,这些限制条款感觉颇像不平等条约, 是不是让你大开眼界了呢? 其实这些限制有一部分应该当作bug来论处, 只是对Qt编程影响不算太大,可暂时忽略,所以被归入优先级很低的问题处理了(意思就是可能永远都不改了)。

转载于:https://www.cnblogs.com/sunpan822/p/8677474.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/255074.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

庖丁解牛TLD(三)——算法初始化

上一讲我提到对于算法的初始化工作主要是在tldInit这个函数里实现的。主要分为如下几大步骤,1)初始化Detector。2)初始化Trajectory。3)训练Detector 1)初始化Detector 其中bb_scan为扫描grid区域,该函数输入为boundin…

Web测试容易忽略的地方

1.浏览器的后退按钮 提交表单一条已经成功提交的记录,back后再提交,看系统会如何处理。检查多次使用back健的情况在有back的地方,back,回到原来的页面,再back,重复几次,看是否会报错。 2.通过修…

[Android]你不知道的Android进程化(4)--进程通信AIDL框架

大家好,我系苍王。以下是我这个系列的相关文章,有兴趣可以参考一下,可以给个喜欢或者关注我的文章。[Android]如何做一个崩溃率少于千分之三噶应用app--章节列表Google爸爸,听说要将一些插件化hook系统的变量属性禁用,…

在未启动程序情况 点击视图设计器 弹出未将对象引用窗体的解决方案

请问下 在未运行程序情况 点击视图设计器 弹出未将对象引用窗体 解决方案:1.看后台进程是不是相关的进程在启动,如果有关闭进程;重启vs,即可2.重启电脑转载于:https://www.cnblogs.com/yang12311/p/5593838.html

图像配准的步骤

目前,很难找到一种普适的方法能够应对所有的配准情况,任何一种配准算法都必须考虑图像的成像原理、几何变形、噪声影响、配准精度等因素。不过,从原理上将,配准算法可以大致分为以下四个步骤: (1&#xff0…

Jm86中的encode_one_macroblock注释

Jm86中的encode_one_macroblock注释 /*! ************************************************************************************** /brief* Mode Decision for a macroblock* //该函数的作用是编码一个宏块(包括帧间、帧内、帧内预测的方式)。*…

Python之路【第十七篇】:装饰器

写代码的时候有一个原则,开放封闭原则(面向对象):对某些东西开放,对某些封闭,在装饰器这里,函数内部是封闭的,不允许改变函数的内部。 装饰器用来装饰函数,可以让函数在执行之前或者执行之后&am…

HALCON示例程序measure_chip.hdev芯片封装检测

HALCON示例程序measure_chip.hdev芯片封装检测 示例程序源码(加注释) 关于显示类函数解释 dev_update_off () read_image (Image, ‘die_on_chip’) get_image_size (Image, Width, Height) dev_close_window () dev_open_window (0, 0, Width * 2, He…

工业机器人智能发展:视觉和触觉感应简化

机器人工业协会(Robotic Industries Association)指出,从2003到2005年间,北美机器人工业以20%的平均年增长率发展。在汽车市场需求疲软以及外国厂商的压力不断增加的背景下,这一成就是如何取得的?成本的普遍…

ASP站点无法访问怎么办

确保启用了目录浏览功能 转载于:https://www.cnblogs.com/acetaohai123/p/6571257.html

五、案例-指令参考-freemarker指令、表达式

案例-指令参考描述&#xff1a;本人自己测试写了一遍&#xff0c;如有错的地方&#xff0c;懂freemarker的朋友望指点指点&#xff01; 案例-指令参考 表达式 一、 Assign 1、<#assign name1"北京" name2"上海" name3"广东"> 调用&#xf…

PartitionMotionSearch()函数

encode_one_macroblock()函数中的运动估计分为两大块&#xff0c;对于宏块级的三种模式&#xff0c;分块后直接对patition依次调用PartitionMotionSearch()函数&#xff1b;而对于亚宏块级的&#xff08;含8x8, 8x4,4x8,4x4&#xff09;模式&#xff0c;首先将宏块拆分为4个88子…

201521123017 《Java程序设计》第4周学习总结

1. 本周学习总结 2. 书面作业 Q1.注释的应用 使用类的注释与方法的注释为前面编写的类与方法进行注释&#xff0c;并在Eclipse中查看。(截图) Q2.面向对象设计(大作业1&#xff0c;非常重要) 2.1 将在网上商城购物或者在班级博客进行学习这一过程&#xff0c;描述成一个故事。…

完整的VAL3程序

start() begin//延时10秒 delay(5)//初始化变量call init()//清空原有运动堆栈resetMotion()//建立上电任务taskCreate "robotpower",100,robotpower()wait(isPowered())//建立生产任务taskCreate "ProductionCycle",10,ProductionCycle()//建立安全区域…

iOS WebView 加载本地资源(图片,文件等)

NSString *path [[NSBundle mainBundle] pathForResource:"关于.docx" ofType:nil]; NSURL *url [NSURL fileURLWithPath:path]; NSLog("%", [self mimeType:url]); //webview加载本地文件&#xff0c;可以使用加载数据的方式 //第一个诶参数是一个N…

本文以H264视频流为例,讲解解码流数据的步骤。

本文以H264视频流为例&#xff0c;讲解解码流数据的步骤。 为突出重点&#xff0c;本文只专注于讨论解码视频流数据&#xff0c;不涉及其它&#xff08;如开发环境的配置等&#xff09;。如果您需要这方面的信息&#xff0c;请和我联系。 准备变量 定义AVCodecContext。如…

2008-2021年商业银行数据(农商行、城商行、国有行、股份制银行)

2008-2021年商业银行数据&#xff08;农商行、城商行、国有行、股份制银行&#xff09; 1、时间&#xff1a;2008-2021年 2、范围&#xff1a;1700银行 3 、指标&#xff1a;证券简称、year、证券代码、资产总计、负债合计、所有者权益合计、利润总额、净利润、贷款总额、存…

EPSON 任务同步 改写

有时需要在多个任务执行之前来使它们同步。如果预先知道执行每项任务所需要的时间&#xff0c;它们就可以通过简单地等待由最慢的任务产生的信号来实现同步。然而&#xff0c;如果不知道那个任务是最慢的&#xff0c;就需要使用一个更复杂的同步化机制&#xff0c;如下所示VAL …

线程池的简单使用

创建指定线程数量的线程池 private static ExecutorService scheduledTaskFactoryExecutor null;private boolean isCancled false;private static class ThreadFactoryTest implements ThreadFactory { Overridepublic Thread newThread(Runnable r) { Thread threa…

异常--自定义异常类

为什么要调用父类构造器? http://blog.csdn.net/rockpk008/article/details/52951856 转载于:https://www.cnblogs.com/dwj-ngu/p/6576382.html